@1claw/cli 0.36.6 → 0.37.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (188) hide show
  1. package/README.md +66 -1
  2. package/dist/bundled-templates/registry.yaml +62 -0
  3. package/dist/bundled-templates/templates/agentkit/Dockerfile +28 -0
  4. package/dist/bundled-templates/templates/agentkit/README.md +36 -0
  5. package/dist/bundled-templates/templates/agentkit/agent.py +83 -0
  6. package/dist/bundled-templates/templates/agentkit/entrypoint.sh +34 -0
  7. package/dist/bundled-templates/templates/agentkit/requirements.txt +5 -0
  8. package/dist/bundled-templates/templates/agentkit/template.yaml +24 -0
  9. package/dist/bundled-templates/templates/agno/Dockerfile +28 -0
  10. package/dist/bundled-templates/templates/agno/README.md +36 -0
  11. package/dist/bundled-templates/templates/agno/agent.py +86 -0
  12. package/dist/bundled-templates/templates/agno/entrypoint.sh +34 -0
  13. package/dist/bundled-templates/templates/agno/requirements.txt +2 -0
  14. package/dist/bundled-templates/templates/agno/template.yaml +24 -0
  15. package/dist/bundled-templates/templates/coder/Dockerfile +28 -0
  16. package/dist/bundled-templates/templates/coder/README.md +36 -0
  17. package/dist/bundled-templates/templates/coder/agent.py +119 -0
  18. package/dist/bundled-templates/templates/coder/entrypoint.sh +34 -0
  19. package/dist/bundled-templates/templates/coder/requirements.txt +4 -0
  20. package/dist/bundled-templates/templates/coder/template.yaml +24 -0
  21. package/dist/bundled-templates/templates/crewai/Dockerfile +28 -0
  22. package/dist/bundled-templates/templates/crewai/README.md +29 -0
  23. package/dist/bundled-templates/templates/crewai/agent.py +109 -0
  24. package/dist/bundled-templates/templates/crewai/entrypoint.sh +34 -0
  25. package/dist/bundled-templates/templates/crewai/requirements.txt +3 -0
  26. package/dist/bundled-templates/templates/crewai/template.yaml +24 -0
  27. package/dist/bundled-templates/templates/elizaos/Dockerfile +31 -0
  28. package/dist/bundled-templates/templates/elizaos/README.md +36 -0
  29. package/dist/bundled-templates/templates/elizaos/agent.ts +100 -0
  30. package/dist/bundled-templates/templates/elizaos/entrypoint.sh +34 -0
  31. package/dist/bundled-templates/templates/elizaos/package.json +18 -0
  32. package/dist/bundled-templates/templates/elizaos/template.yaml +25 -0
  33. package/dist/bundled-templates/templates/elizaos/tsconfig.json +12 -0
  34. package/dist/bundled-templates/templates/langchain/Dockerfile +28 -0
  35. package/dist/bundled-templates/templates/langchain/README.md +37 -0
  36. package/dist/bundled-templates/templates/langchain/agent.py +115 -0
  37. package/dist/bundled-templates/templates/langchain/entrypoint.sh +36 -0
  38. package/dist/bundled-templates/templates/langchain/requirements.txt +4 -0
  39. package/dist/bundled-templates/templates/langchain/template.yaml +24 -0
  40. package/dist/bundled-templates/templates/llamaindex/Dockerfile +28 -0
  41. package/dist/bundled-templates/templates/llamaindex/README.md +36 -0
  42. package/dist/bundled-templates/templates/llamaindex/agent.py +97 -0
  43. package/dist/bundled-templates/templates/llamaindex/entrypoint.sh +34 -0
  44. package/dist/bundled-templates/templates/llamaindex/requirements.txt +3 -0
  45. package/dist/bundled-templates/templates/llamaindex/template.yaml +24 -0
  46. package/dist/bundled-templates/templates/mastra/Dockerfile +31 -0
  47. package/dist/bundled-templates/templates/mastra/README.md +31 -0
  48. package/dist/bundled-templates/templates/mastra/agent.ts +112 -0
  49. package/dist/bundled-templates/templates/mastra/entrypoint.sh +34 -0
  50. package/dist/bundled-templates/templates/mastra/package.json +17 -0
  51. package/dist/bundled-templates/templates/mastra/template.yaml +25 -0
  52. package/dist/bundled-templates/templates/mastra/tsconfig.json +12 -0
  53. package/dist/bundled-templates/templates/openai-agents/Dockerfile +28 -0
  54. package/dist/bundled-templates/templates/openai-agents/README.md +29 -0
  55. package/dist/bundled-templates/templates/openai-agents/agent.py +98 -0
  56. package/dist/bundled-templates/templates/openai-agents/entrypoint.sh +34 -0
  57. package/dist/bundled-templates/templates/openai-agents/requirements.txt +3 -0
  58. package/dist/bundled-templates/templates/openai-agents/template.yaml +24 -0
  59. package/dist/bundled-templates/templates/pydantic-ai/Dockerfile +28 -0
  60. package/dist/bundled-templates/templates/pydantic-ai/README.md +36 -0
  61. package/dist/bundled-templates/templates/pydantic-ai/agent.py +110 -0
  62. package/dist/bundled-templates/templates/pydantic-ai/entrypoint.sh +34 -0
  63. package/dist/bundled-templates/templates/pydantic-ai/requirements.txt +2 -0
  64. package/dist/bundled-templates/templates/pydantic-ai/template.yaml +24 -0
  65. package/dist/bundled-templates/templates/smolagents/Dockerfile +28 -0
  66. package/dist/bundled-templates/templates/smolagents/README.md +36 -0
  67. package/dist/bundled-templates/templates/smolagents/agent.py +97 -0
  68. package/dist/bundled-templates/templates/smolagents/entrypoint.sh +34 -0
  69. package/dist/bundled-templates/templates/smolagents/requirements.txt +2 -0
  70. package/dist/bundled-templates/templates/smolagents/template.yaml +24 -0
  71. package/dist/bundled-templates/templates/typescript-sdk/Dockerfile +31 -0
  72. package/dist/bundled-templates/templates/typescript-sdk/README.md +29 -0
  73. package/dist/bundled-templates/templates/typescript-sdk/agent.ts +130 -0
  74. package/dist/bundled-templates/templates/typescript-sdk/entrypoint.sh +34 -0
  75. package/dist/bundled-templates/templates/typescript-sdk/package.json +17 -0
  76. package/dist/bundled-templates/templates/typescript-sdk/template.yaml +25 -0
  77. package/dist/bundled-templates/templates/typescript-sdk/tsconfig.json +12 -0
  78. package/dist/src/commands/init.d.ts.map +1 -1
  79. package/dist/src/commands/init.js +10 -255
  80. package/dist/src/commands/init.js.map +1 -1
  81. package/dist/src/commands/spawn.d.ts +3 -0
  82. package/dist/src/commands/spawn.d.ts.map +1 -0
  83. package/dist/src/commands/spawn.js +408 -0
  84. package/dist/src/commands/spawn.js.map +1 -0
  85. package/dist/src/index.d.ts.map +1 -1
  86. package/dist/src/index.js +2 -0
  87. package/dist/src/index.js.map +1 -1
  88. package/dist/src/lib/container-config.d.ts +3 -1
  89. package/dist/src/lib/container-config.d.ts.map +1 -1
  90. package/dist/src/lib/container-config.js +3 -2
  91. package/dist/src/lib/container-config.js.map +1 -1
  92. package/dist/src/lib/module-deprecation.d.ts +8 -0
  93. package/dist/src/lib/module-deprecation.d.ts.map +1 -0
  94. package/dist/src/lib/module-deprecation.js +15 -0
  95. package/dist/src/lib/module-deprecation.js.map +1 -0
  96. package/dist/src/lib/paths.d.ts +12 -0
  97. package/dist/src/lib/paths.d.ts.map +1 -1
  98. package/dist/src/lib/paths.js +42 -1
  99. package/dist/src/lib/paths.js.map +1 -1
  100. package/dist/src/lib/provisioning.d.ts +30 -0
  101. package/dist/src/lib/provisioning.d.ts.map +1 -0
  102. package/dist/src/lib/provisioning.js +256 -0
  103. package/dist/src/lib/provisioning.js.map +1 -0
  104. package/dist/src/registry.yaml +62 -0
  105. package/dist/src/templates/agentkit/Dockerfile +34 -0
  106. package/dist/src/templates/agentkit/README.md +36 -0
  107. package/dist/src/templates/agentkit/agent.py +83 -0
  108. package/dist/src/templates/agentkit/entrypoint.sh +34 -0
  109. package/dist/src/templates/agentkit/requirements.txt +5 -0
  110. package/dist/src/templates/agentkit/template.yaml +24 -0
  111. package/dist/src/templates/agno/Dockerfile +34 -0
  112. package/dist/src/templates/agno/README.md +36 -0
  113. package/dist/src/templates/agno/agent.py +86 -0
  114. package/dist/src/templates/agno/entrypoint.sh +34 -0
  115. package/dist/src/templates/agno/requirements.txt +2 -0
  116. package/dist/src/templates/agno/template.yaml +24 -0
  117. package/dist/src/templates/coder/Dockerfile +34 -0
  118. package/dist/src/templates/coder/README.md +36 -0
  119. package/dist/src/templates/coder/agent.py +119 -0
  120. package/dist/src/templates/coder/entrypoint.sh +34 -0
  121. package/dist/src/templates/coder/requirements.txt +4 -0
  122. package/dist/src/templates/coder/template.yaml +24 -0
  123. package/dist/src/templates/crewai/Dockerfile +34 -0
  124. package/dist/src/templates/crewai/README.md +29 -0
  125. package/dist/src/templates/crewai/agent.py +109 -0
  126. package/dist/src/templates/crewai/entrypoint.sh +34 -0
  127. package/dist/src/templates/crewai/requirements.txt +3 -0
  128. package/dist/src/templates/crewai/template.yaml +24 -0
  129. package/dist/src/templates/elizaos/Dockerfile +31 -0
  130. package/dist/src/templates/elizaos/README.md +36 -0
  131. package/dist/src/templates/elizaos/agent.ts +100 -0
  132. package/dist/src/templates/elizaos/entrypoint.sh +34 -0
  133. package/dist/src/templates/elizaos/package.json +18 -0
  134. package/dist/src/templates/elizaos/template.yaml +25 -0
  135. package/dist/src/templates/elizaos/tsconfig.json +12 -0
  136. package/dist/src/templates/fetcher.d.ts +20 -0
  137. package/dist/src/templates/fetcher.d.ts.map +1 -0
  138. package/dist/src/templates/fetcher.js +189 -0
  139. package/dist/src/templates/fetcher.js.map +1 -0
  140. package/dist/src/templates/langchain/Dockerfile +34 -0
  141. package/dist/src/templates/langchain/README.md +37 -0
  142. package/dist/src/templates/langchain/agent.py +115 -0
  143. package/dist/src/templates/langchain/entrypoint.sh +36 -0
  144. package/dist/src/templates/langchain/requirements.txt +4 -0
  145. package/dist/src/templates/langchain/template.yaml +24 -0
  146. package/dist/src/templates/llamaindex/Dockerfile +34 -0
  147. package/dist/src/templates/llamaindex/README.md +36 -0
  148. package/dist/src/templates/llamaindex/agent.py +97 -0
  149. package/dist/src/templates/llamaindex/entrypoint.sh +34 -0
  150. package/dist/src/templates/llamaindex/requirements.txt +3 -0
  151. package/dist/src/templates/llamaindex/template.yaml +24 -0
  152. package/dist/src/templates/mastra/Dockerfile +31 -0
  153. package/dist/src/templates/mastra/README.md +31 -0
  154. package/dist/src/templates/mastra/agent.ts +112 -0
  155. package/dist/src/templates/mastra/entrypoint.sh +34 -0
  156. package/dist/src/templates/mastra/package.json +17 -0
  157. package/dist/src/templates/mastra/template.yaml +25 -0
  158. package/dist/src/templates/mastra/tsconfig.json +12 -0
  159. package/dist/src/templates/openai-agents/Dockerfile +34 -0
  160. package/dist/src/templates/openai-agents/README.md +29 -0
  161. package/dist/src/templates/openai-agents/agent.py +98 -0
  162. package/dist/src/templates/openai-agents/entrypoint.sh +34 -0
  163. package/dist/src/templates/openai-agents/requirements.txt +3 -0
  164. package/dist/src/templates/openai-agents/template.yaml +24 -0
  165. package/dist/src/templates/pydantic-ai/Dockerfile +34 -0
  166. package/dist/src/templates/pydantic-ai/README.md +36 -0
  167. package/dist/src/templates/pydantic-ai/agent.py +110 -0
  168. package/dist/src/templates/pydantic-ai/entrypoint.sh +34 -0
  169. package/dist/src/templates/pydantic-ai/requirements.txt +2 -0
  170. package/dist/src/templates/pydantic-ai/template.yaml +24 -0
  171. package/dist/src/templates/registry.d.ts +48 -0
  172. package/dist/src/templates/registry.d.ts.map +1 -0
  173. package/dist/src/templates/registry.js +168 -0
  174. package/dist/src/templates/registry.js.map +1 -0
  175. package/dist/src/templates/smolagents/Dockerfile +34 -0
  176. package/dist/src/templates/smolagents/README.md +36 -0
  177. package/dist/src/templates/smolagents/agent.py +97 -0
  178. package/dist/src/templates/smolagents/entrypoint.sh +34 -0
  179. package/dist/src/templates/smolagents/requirements.txt +2 -0
  180. package/dist/src/templates/smolagents/template.yaml +24 -0
  181. package/dist/src/templates/typescript-sdk/Dockerfile +31 -0
  182. package/dist/src/templates/typescript-sdk/README.md +29 -0
  183. package/dist/src/templates/typescript-sdk/agent.ts +130 -0
  184. package/dist/src/templates/typescript-sdk/entrypoint.sh +34 -0
  185. package/dist/src/templates/typescript-sdk/package.json +17 -0
  186. package/dist/src/templates/typescript-sdk/template.yaml +25 -0
  187. package/dist/src/templates/typescript-sdk/tsconfig.json +12 -0
  188. package/package.json +1 -1
@@ -0,0 +1,119 @@
1
+ """
2
+ Coder workspace automation agent pre-wired with 1Claw MCP for secrets.
3
+
4
+ Manages Coder workspaces via the Coder API. LLM calls are routed through
5
+ Shroud when ONECLAW_LLM_VIA_SHROUD is set. The container never sees raw
6
+ API keys — they are injected by the host daemon.
7
+ """
8
+
9
+ import os
10
+ import asyncio
11
+ import httpx
12
+ from flask import Flask, request, jsonify
13
+ from agents import Agent, Runner, function_tool
14
+
15
+ app = Flask(__name__)
16
+
17
+ SHROUD_URL = os.environ.get("ONECLAW_SHROUD_URL", "https://shroud.1claw.xyz")
18
+ LLM_VIA_SHROUD = os.environ.get("ONECLAW_LLM_VIA_SHROUD", "").lower() == "true"
19
+ MODEL = os.environ.get("ONECLAW_SHROUD_MODEL", "gpt-4o-mini")
20
+ CODER_URL = os.environ.get("CODER_URL", "")
21
+ CODER_TOKEN = os.environ.get("CODER_SESSION_TOKEN", "")
22
+
23
+
24
+ @function_tool
25
+ def list_workspaces() -> str:
26
+ """List all Coder workspaces accessible to the agent."""
27
+ if not CODER_URL or not CODER_TOKEN:
28
+ return "CODER_URL and CODER_SESSION_TOKEN not configured. Set them via 1Claw vault."
29
+ try:
30
+ r = httpx.get(
31
+ f"{CODER_URL}/api/v2/workspaces",
32
+ headers={"Coder-Session-Token": CODER_TOKEN},
33
+ timeout=10,
34
+ )
35
+ r.raise_for_status()
36
+ workspaces = r.json().get("workspaces", [])
37
+ if not workspaces:
38
+ return "No workspaces found."
39
+ return "\n".join(
40
+ f" {w['name']} ({w.get('latest_build', {}).get('status', 'unknown')})"
41
+ for w in workspaces
42
+ )
43
+ except Exception as e:
44
+ return f"Error listing workspaces: {e}"
45
+
46
+
47
+ @function_tool
48
+ def list_env_vars() -> str:
49
+ """List 1Claw-related environment variables (values redacted)."""
50
+ prefix = "ONECLAW_"
51
+ vars_list = [k for k in sorted(os.environ) if k.startswith(prefix)]
52
+ return "\n".join(f" {k}=***" for k in vars_list) if vars_list else "No ONECLAW_* vars set."
53
+
54
+
55
+ def create_agent() -> Agent | None:
56
+ """Build the Coder automation agent. Returns None if no LLM."""
57
+ if not LLM_VIA_SHROUD:
58
+ return None
59
+
60
+ os.environ["OPENAI_BASE_URL"] = f"{SHROUD_URL}/v1"
61
+ os.environ["OPENAI_API_KEY"] = "shroud-injected"
62
+
63
+ return Agent(
64
+ name="1Claw Coder Agent",
65
+ instructions=(
66
+ "You are a workspace automation agent running inside 1Claw. "
67
+ "You can list and manage Coder workspaces. Coder credentials "
68
+ "are injected via the 1Claw daemon — never ask the user for tokens."
69
+ ),
70
+ tools=[list_workspaces, list_env_vars],
71
+ model=MODEL,
72
+ )
73
+
74
+
75
+ agent = create_agent()
76
+
77
+
78
+ @app.route("/health")
79
+ def health():
80
+ return jsonify({"status": "ok", "framework": "coder", "llm_wired": LLM_VIA_SHROUD})
81
+
82
+
83
+ @app.route("/chat", methods=["POST"])
84
+ def chat():
85
+ data = request.get_json(silent=True) or {}
86
+ message = data.get("message", "").strip()
87
+ if not message:
88
+ return jsonify({"error": "No message provided"}), 400
89
+
90
+ if not agent:
91
+ return jsonify({
92
+ "response": "No LLM configured. Use --llm-api-key or enable Token Billing.",
93
+ "framework": "coder",
94
+ })
95
+
96
+ try:
97
+ result = asyncio.run(Runner.run(agent, message))
98
+ return jsonify({"response": result.final_output, "framework": "coder"})
99
+ except Exception as e:
100
+ return jsonify({"error": str(e)}), 500
101
+
102
+
103
+ @app.route("/")
104
+ def index():
105
+ return """<!DOCTYPE html>
106
+ <html><head><title>1Claw Coder Agent</title></head>
107
+ <body style="font-family:system-ui;max-width:600px;margin:40px auto;padding:0 20px">
108
+ <h1>1Claw Coder Workspace Agent</h1>
109
+ <p>Send messages via <code>POST /chat</code> with <code>{"message": "..."}</code></p>
110
+ <p>Health: <a href="/health">/health</a></p>
111
+ <p style="color:#666;font-size:0.9em">
112
+ Credentials stay in the host daemon — this container never sees secret values.
113
+ </p></body></html>"""
114
+
115
+
116
+ if __name__ == "__main__":
117
+ port = int(os.environ.get("CHAT_UI_PORT", "3000"))
118
+ print(f"Coder agent listening on http://0.0.0.0:{port}")
119
+ app.run(host="0.0.0.0", port=port)
@@ -0,0 +1,34 @@
1
+ #!/bin/sh
2
+ set -e
3
+
4
+ DAEMON_SOCKET="${ONECLAW_DAEMON_SOCKET:-/run/1claw/daemon.sock}"
5
+ CHAT_UI_PORT="${CHAT_UI_PORT:-3000}"
6
+
7
+ echo "─────────────────────────────────────────────"
8
+ echo " 1Claw Coder Agent"
9
+ echo " Framework: coder"
10
+ echo " Agent ID: ${ONECLAW_AGENT_ID:-not set}"
11
+
12
+ if [ -S "$DAEMON_SOCKET" ]; then
13
+ echo " Mode: ${ONECLAW_MODE:-cloud} (daemon socket)"
14
+ echo " Socket: $DAEMON_SOCKET"
15
+ else
16
+ echo " Mode: standalone (no daemon socket)"
17
+ fi
18
+ echo "─────────────────────────────────────────────"
19
+
20
+ if [ "$ONECLAW_LLM_VIA_SHROUD" = "true" ]; then
21
+ export OPENAI_BASE_URL="${ONECLAW_SHROUD_URL}/v1"
22
+ echo "LLM routed through Shroud: ${ONECLAW_SHROUD_PROVIDER}/${ONECLAW_SHROUD_MODEL}"
23
+ fi
24
+
25
+ if [ -S "$DAEMON_SOCKET" ]; then
26
+ if command -v 1claw-mcp >/dev/null 2>&1; then
27
+ ONECLAW_LOCAL_VAULT=true ONECLAW_DAEMON_SOCKET="$DAEMON_SOCKET" \
28
+ 1claw-mcp --local 2>/tmp/mcp.log &
29
+ echo "MCP server started in background."
30
+ fi
31
+ fi
32
+
33
+ echo "Ready: http://0.0.0.0:${CHAT_UI_PORT}"
34
+ exec python agent.py
@@ -0,0 +1,4 @@
1
+ openai-agents>=0.1.0
2
+ openai>=1.50.0
3
+ httpx>=0.27.0
4
+ flask>=3.0.0
@@ -0,0 +1,24 @@
1
+ name: coder
2
+ display_name: "Coder"
3
+ version: 1.0.0
4
+ description: "Coder workspace automation agent"
5
+ author: 1Claw
6
+ language: python
7
+ homepage: https://coder.com
8
+
9
+ docker:
10
+ base_image: python:3.12-slim
11
+ context_files:
12
+ - Dockerfile
13
+ - requirements.txt
14
+ - agent.py
15
+ - entrypoint.sh
16
+ env:
17
+ ONECLAW_FRAMEWORK: coder
18
+ health_endpoint: /health
19
+ health_port: 3000
20
+
21
+ post_spawn_message: |
22
+ Edit agent.py to customize your Coder workspace automation.
23
+ Your 1Claw MCP server is available at the daemon socket.
24
+ LLM calls are routed through Shroud for inspection and redaction.
@@ -0,0 +1,28 @@
1
+ FROM python:3.12-slim
2
+
3
+ RUN apt-get update && apt-get install -y --no-install-recommends \
4
+ curl tini && \
5
+ rm -rf /var/lib/apt/lists/*
6
+
7
+ WORKDIR /app
8
+
9
+ COPY requirements.txt .
10
+ RUN pip install --no-cache-dir -r requirements.txt
11
+
12
+ COPY agent.py .
13
+ COPY entrypoint.sh .
14
+ RUN chmod +x entrypoint.sh
15
+
16
+ RUN mkdir -p /run/1claw
17
+
18
+ ENV NODE_ENV=production
19
+ ENV ONECLAW_DAEMON_SOCKET=/run/1claw/daemon.sock
20
+ ENV ONECLAW_FRAMEWORK=crewai
21
+
22
+ EXPOSE 3000
23
+
24
+ HEALTHCHECK --interval=10s --timeout=3s --start-period=10s --retries=5 \
25
+ CMD curl -sf http://localhost:3000/health || exit 1
26
+
27
+ ENTRYPOINT ["tini", "--"]
28
+ CMD ["./entrypoint.sh"]
@@ -0,0 +1,29 @@
1
+ # CrewAI Template
2
+
3
+ A multi-agent crew using [CrewAI](https://crewai.com) with 1Claw MCP for
4
+ secrets management and on-chain signing.
5
+
6
+ ## Quick start
7
+
8
+ ```bash
9
+ 1claw spawn crewai
10
+ ```
11
+
12
+ Or with your own API key:
13
+
14
+ ```bash
15
+ 1claw spawn crewai --llm-api-key sk-...
16
+ ```
17
+
18
+ ## What's included
19
+
20
+ - **agent.py** — Starter crew with Researcher and Writer agents
21
+ - **Flask server** on port 3000 with `/chat` and `/health` endpoints
22
+ - **Shroud integration** — LLM calls are routed through Shroud for inspection
23
+ - **MCP server** — started automatically for tool access to 1Claw vault
24
+
25
+ ## Customizing
26
+
27
+ Edit `agent.py` to add your own agents, tools, and tasks. The crew uses
28
+ CrewAI's `LLM` class pointed at Shroud, which handles provider routing
29
+ transparently.
@@ -0,0 +1,109 @@
1
+ """
2
+ CrewAI multi-agent crew pre-wired with 1Claw MCP for secrets and signing.
3
+
4
+ LLM calls are routed through Shroud when ONECLAW_LLM_VIA_SHROUD is set.
5
+ The container never sees raw API keys — they are injected by the host daemon.
6
+ """
7
+
8
+ import os
9
+ from flask import Flask, request, jsonify
10
+ from crewai import Agent, Task, Crew, LLM
11
+
12
+ app = Flask(__name__)
13
+
14
+ SHROUD_URL = os.environ.get("ONECLAW_SHROUD_URL", "https://shroud.1claw.xyz")
15
+ LLM_VIA_SHROUD = os.environ.get("ONECLAW_LLM_VIA_SHROUD", "").lower() == "true"
16
+ PROVIDER = os.environ.get("ONECLAW_SHROUD_PROVIDER", "openai")
17
+ MODEL = os.environ.get("ONECLAW_SHROUD_MODEL", "gpt-4o-mini")
18
+
19
+
20
+ def create_crew() -> Crew | None:
21
+ """Build a CrewAI crew. Returns None if no LLM is configured."""
22
+ if not LLM_VIA_SHROUD:
23
+ return None
24
+
25
+ llm = LLM(
26
+ model=f"{PROVIDER}/{MODEL}",
27
+ base_url=f"{SHROUD_URL}/v1",
28
+ api_key="shroud-injected",
29
+ )
30
+
31
+ researcher = Agent(
32
+ role="Researcher",
33
+ goal="Find accurate and relevant information",
34
+ backstory="You are a skilled researcher who excels at finding and synthesizing information.",
35
+ llm=llm,
36
+ verbose=False,
37
+ )
38
+
39
+ writer = Agent(
40
+ role="Writer",
41
+ goal="Create clear, concise, and engaging content",
42
+ backstory="You are a talented writer who turns research into readable content.",
43
+ llm=llm,
44
+ verbose=False,
45
+ )
46
+
47
+ return Crew(agents=[researcher, writer], verbose=False), researcher, writer
48
+
49
+
50
+ crew_result = create_crew()
51
+ crew = crew_result[0] if crew_result else None
52
+ researcher = crew_result[1] if crew_result else None
53
+ writer = crew_result[2] if crew_result else None
54
+
55
+
56
+ @app.route("/health")
57
+ def health():
58
+ return jsonify({"status": "ok", "framework": "crewai", "llm_wired": LLM_VIA_SHROUD})
59
+
60
+
61
+ @app.route("/chat", methods=["POST"])
62
+ def chat():
63
+ data = request.get_json(silent=True) or {}
64
+ message = data.get("message", "").strip()
65
+ if not message:
66
+ return jsonify({"error": "No message provided"}), 400
67
+
68
+ if not crew:
69
+ return jsonify({
70
+ "response": "No LLM configured. Use --llm-api-key or enable Token Billing.",
71
+ "framework": "crewai",
72
+ })
73
+
74
+ try:
75
+ research_task = Task(
76
+ description=f"Research the following topic: {message}",
77
+ expected_output="A concise summary of key findings.",
78
+ agent=researcher,
79
+ )
80
+
81
+ write_task = Task(
82
+ description="Write a clear response based on the research findings.",
83
+ expected_output="A well-written, informative response.",
84
+ agent=writer,
85
+ )
86
+
87
+ result = crew.kickoff(tasks=[research_task, write_task])
88
+ return jsonify({"response": str(result), "framework": "crewai"})
89
+ except Exception as e:
90
+ return jsonify({"error": str(e)}), 500
91
+
92
+
93
+ @app.route("/")
94
+ def index():
95
+ return """<!DOCTYPE html>
96
+ <html><head><title>1Claw CrewAI Agent</title></head>
97
+ <body style="font-family:system-ui;max-width:600px;margin:40px auto;padding:0 20px">
98
+ <h1>1Claw CrewAI Agent</h1>
99
+ <p>Send messages via <code>POST /chat</code> with <code>{"message": "..."}</code></p>
100
+ <p>Health: <a href="/health">/health</a></p>
101
+ <p style="color:#666;font-size:0.9em">
102
+ Credentials stay in the host daemon — this container never sees secret values.
103
+ </p></body></html>"""
104
+
105
+
106
+ if __name__ == "__main__":
107
+ port = int(os.environ.get("CHAT_UI_PORT", "3000"))
108
+ print(f"CrewAI agent listening on http://0.0.0.0:{port}")
109
+ app.run(host="0.0.0.0", port=port)
@@ -0,0 +1,34 @@
1
+ #!/bin/sh
2
+ set -e
3
+
4
+ DAEMON_SOCKET="${ONECLAW_DAEMON_SOCKET:-/run/1claw/daemon.sock}"
5
+ CHAT_UI_PORT="${CHAT_UI_PORT:-3000}"
6
+
7
+ echo "─────────────────────────────────────────────"
8
+ echo " 1Claw CrewAI Agent"
9
+ echo " Framework: crewai"
10
+ echo " Agent ID: ${ONECLAW_AGENT_ID:-not set}"
11
+
12
+ if [ -S "$DAEMON_SOCKET" ]; then
13
+ echo " Mode: ${ONECLAW_MODE:-cloud} (daemon socket)"
14
+ echo " Socket: $DAEMON_SOCKET"
15
+ else
16
+ echo " Mode: standalone (no daemon socket)"
17
+ fi
18
+ echo "─────────────────────────────────────────────"
19
+
20
+ if [ "$ONECLAW_LLM_VIA_SHROUD" = "true" ]; then
21
+ export OPENAI_BASE_URL="${ONECLAW_SHROUD_URL}/v1"
22
+ echo "LLM routed through Shroud: ${ONECLAW_SHROUD_PROVIDER}/${ONECLAW_SHROUD_MODEL}"
23
+ fi
24
+
25
+ if [ -S "$DAEMON_SOCKET" ]; then
26
+ if command -v 1claw-mcp >/dev/null 2>&1; then
27
+ ONECLAW_LOCAL_VAULT=true ONECLAW_DAEMON_SOCKET="$DAEMON_SOCKET" \
28
+ 1claw-mcp --local 2>/tmp/mcp.log &
29
+ echo "MCP server started in background."
30
+ fi
31
+ fi
32
+
33
+ echo "Ready: http://0.0.0.0:${CHAT_UI_PORT}"
34
+ exec python agent.py
@@ -0,0 +1,3 @@
1
+ crewai>=0.80.0
2
+ crewai-tools>=0.14.0
3
+ flask>=3.0.0
@@ -0,0 +1,24 @@
1
+ name: crewai
2
+ display_name: "CrewAI"
3
+ version: 1.0.0
4
+ description: "Multi-agent crew with 1Claw-managed secrets"
5
+ author: 1Claw
6
+ language: python
7
+ homepage: https://crewai.com
8
+
9
+ docker:
10
+ base_image: python:3.12-slim
11
+ context_files:
12
+ - Dockerfile
13
+ - requirements.txt
14
+ - agent.py
15
+ - entrypoint.sh
16
+ env:
17
+ ONECLAW_FRAMEWORK: crewai
18
+ health_endpoint: /health
19
+ health_port: 3000
20
+
21
+ post_spawn_message: |
22
+ Edit agent.py to define your crew's agents, tasks, and workflow.
23
+ Your 1Claw MCP server is available at the daemon socket.
24
+ LLM calls are routed through Shroud for inspection and redaction.
@@ -0,0 +1,31 @@
1
+ FROM node:22-slim
2
+
3
+ RUN apt-get update && apt-get install -y --no-install-recommends \
4
+ curl tini python3 make g++ && \
5
+ rm -rf /var/lib/apt/lists/*
6
+
7
+ WORKDIR /app
8
+
9
+ COPY package.json tsconfig.json ./
10
+ RUN npm install --omit=dev 2>/dev/null || npm install
11
+
12
+ RUN npm install -g @1claw/mcp@latest 2>/dev/null || \
13
+ echo "WARN: @1claw/mcp install deferred to runtime"
14
+
15
+ COPY agent.ts .
16
+ COPY entrypoint.sh .
17
+ RUN chmod +x entrypoint.sh
18
+
19
+ RUN mkdir -p /run/1claw
20
+
21
+ ENV NODE_ENV=production
22
+ ENV ONECLAW_DAEMON_SOCKET=/run/1claw/daemon.sock
23
+ ENV ONECLAW_FRAMEWORK=elizaos
24
+
25
+ EXPOSE 3000
26
+
27
+ HEALTHCHECK --interval=10s --timeout=3s --start-period=10s --retries=5 \
28
+ CMD curl -sf http://localhost:3000/health || exit 1
29
+
30
+ ENTRYPOINT ["tini", "--"]
31
+ CMD ["./entrypoint.sh"]
@@ -0,0 +1,36 @@
1
+ # 1Claw ElizaOS Agent Template
2
+
3
+ [ElizaOS](https://elizaos.ai) character runtime with 1Claw vault-backed secrets and multi-chain signing via `@1claw/plugin-elizaos`.
4
+
5
+ ## Quick start
6
+
7
+ ```bash
8
+ 1claw spawn elizaos --agent-key ocv_YOUR_KEY
9
+ ```
10
+
11
+ ## What's included
12
+
13
+ - `agent.ts` — ElizaOS agent with Shroud LLM routing and `/chat` + `/health` endpoints
14
+ - `Dockerfile` — Node 22 slim image with `@1claw/mcp` and `@1claw/plugin-elizaos`
15
+ - `entrypoint.sh` — Daemon socket detection, Shroud wiring, MCP server startup
16
+
17
+ ## Plugin actions
18
+
19
+ The `@1claw/plugin-elizaos` plugin provides 8 actions:
20
+ - `GET_SECRET` / `PUT_SECRET` / `LIST_SECRETS` / `DELETE_SECRET`
21
+ - `SIGN_MESSAGE` / `SIGN_TYPED_DATA` / `SUBMIT_TRANSACTION`
22
+ - `LIST_SIGNING_KEYS`
23
+
24
+ ## LLM authentication
25
+
26
+ ```bash
27
+ # Bring your own key (stored in vault, routed through Shroud)
28
+ 1claw spawn elizaos --agent-key ocv_YOUR_KEY --llm-api-key sk-...
29
+
30
+ # Use 1Claw Token Billing (no provider key needed)
31
+ 1claw spawn elizaos --agent-key ocv_YOUR_KEY
32
+ ```
33
+
34
+ ## Customization
35
+
36
+ Edit `agent.ts` to define your character, add custom actions, or integrate with the full ElizaOS `AgentRuntime`.
@@ -0,0 +1,100 @@
1
+ /**
2
+ * ElizaOS agent pre-wired with 1Claw plugin for vault secrets and signing.
3
+ *
4
+ * LLM calls are routed through Shroud when ONECLAW_LLM_VIA_SHROUD is set.
5
+ * The container never sees raw API keys — they are injected by the host daemon.
6
+ */
7
+
8
+ import { createServer } from "node:http";
9
+
10
+ const SHROUD_URL = process.env.ONECLAW_SHROUD_URL ?? "https://shroud.1claw.xyz";
11
+ const LLM_VIA_SHROUD = process.env.ONECLAW_LLM_VIA_SHROUD === "true";
12
+ const PROVIDER = process.env.ONECLAW_SHROUD_PROVIDER ?? "openai";
13
+ const MODEL = process.env.ONECLAW_SHROUD_MODEL ?? "gpt-4o-mini";
14
+ const PORT = parseInt(process.env.CHAT_UI_PORT ?? "3000", 10);
15
+
16
+ const conversationHistory: { role: "user" | "assistant"; content: string }[] = [];
17
+
18
+ /**
19
+ * Minimal chat handler using OpenAI-compatible API through Shroud.
20
+ * Replace with a full ElizaOS AgentRuntime for production use.
21
+ */
22
+ async function handleChat(message: string): Promise<string> {
23
+ if (!LLM_VIA_SHROUD) {
24
+ return "No LLM configured. Use --llm-api-key or enable Token Billing.";
25
+ }
26
+
27
+ conversationHistory.push({ role: "user", content: message });
28
+
29
+ const resp = await fetch(`${SHROUD_URL}/v1/chat/completions`, {
30
+ method: "POST",
31
+ headers: { "Content-Type": "application/json", Authorization: "Bearer shroud-injected" },
32
+ body: JSON.stringify({
33
+ model: MODEL,
34
+ messages: [
35
+ {
36
+ role: "system" as const,
37
+ content:
38
+ "You are an ElizaOS character running inside a secure 1Claw container. " +
39
+ "The @1claw/plugin-elizaos plugin gives you vault access and multi-chain signing. " +
40
+ "Be helpful and concise.",
41
+ },
42
+ ...conversationHistory,
43
+ ],
44
+ }),
45
+ });
46
+
47
+ if (!resp.ok) throw new Error(`LLM error: ${resp.status} ${await resp.text()}`);
48
+
49
+ const data = await resp.json() as any;
50
+ const text = data.choices?.[0]?.message?.content ?? "No response from LLM.";
51
+ conversationHistory.push({ role: "assistant", content: text });
52
+ return text;
53
+ }
54
+
55
+ const server = createServer(async (req, res) => {
56
+ if (req.url === "/health" && req.method === "GET") {
57
+ res.writeHead(200, { "Content-Type": "application/json" });
58
+ res.end(JSON.stringify({ status: "ok", framework: "elizaos", llm_wired: LLM_VIA_SHROUD }));
59
+ return;
60
+ }
61
+
62
+ if (req.url === "/chat" && req.method === "POST") {
63
+ const chunks: Buffer[] = [];
64
+ for await (const chunk of req) chunks.push(chunk as Buffer);
65
+ const body = JSON.parse(Buffer.concat(chunks).toString());
66
+ const message = (body.message ?? "").trim();
67
+
68
+ if (!message) {
69
+ res.writeHead(400, { "Content-Type": "application/json" });
70
+ res.end(JSON.stringify({ error: "No message provided" }));
71
+ return;
72
+ }
73
+
74
+ try {
75
+ const response = await handleChat(message);
76
+ res.writeHead(200, { "Content-Type": "application/json" });
77
+ res.end(JSON.stringify({ response, framework: "elizaos" }));
78
+ } catch (e: any) {
79
+ res.writeHead(500, { "Content-Type": "application/json" });
80
+ res.end(JSON.stringify({ error: e.message }));
81
+ }
82
+ return;
83
+ }
84
+
85
+ res.writeHead(200, { "Content-Type": "text/html" });
86
+ res.end(`<!DOCTYPE html>
87
+ <html><head><title>1Claw ElizaOS Agent</title></head>
88
+ <body style="font-family:system-ui;max-width:600px;margin:40px auto;padding:0 20px">
89
+ <h1>1Claw ElizaOS Agent</h1>
90
+ <p>Send messages via <code>POST /chat</code> with <code>{"message": "..."}</code></p>
91
+ <p>Health: <a href="/health">/health</a></p>
92
+ <p style="color:#666;font-size:0.9em">
93
+ The @1claw/plugin-elizaos plugin provides 8 actions for vault secrets and multi-chain signing.
94
+ Credentials stay in the host daemon — this container never sees secret values.
95
+ </p></body></html>`);
96
+ });
97
+
98
+ server.listen(PORT, "0.0.0.0", () => {
99
+ console.log(`ElizaOS agent listening on http://0.0.0.0:${PORT}`);
100
+ });
@@ -0,0 +1,34 @@
1
+ #!/bin/sh
2
+ set -e
3
+
4
+ DAEMON_SOCKET="${ONECLAW_DAEMON_SOCKET:-/run/1claw/daemon.sock}"
5
+ CHAT_UI_PORT="${CHAT_UI_PORT:-3000}"
6
+
7
+ echo "─────────────────────────────────────────────"
8
+ echo " 1Claw ElizaOS Agent"
9
+ echo " Framework: elizaos (TypeScript)"
10
+ echo " Agent ID: ${ONECLAW_AGENT_ID:-not set}"
11
+
12
+ if [ -S "$DAEMON_SOCKET" ]; then
13
+ echo " Mode: ${ONECLAW_MODE:-cloud} (daemon socket)"
14
+ echo " Socket: $DAEMON_SOCKET"
15
+ else
16
+ echo " Mode: standalone (no daemon socket)"
17
+ fi
18
+ echo "─────────────────────────────────────────────"
19
+
20
+ if [ "$ONECLAW_LLM_VIA_SHROUD" = "true" ]; then
21
+ export OPENAI_BASE_URL="${ONECLAW_SHROUD_URL}/v1"
22
+ echo "LLM routed through Shroud: ${ONECLAW_SHROUD_PROVIDER}/${ONECLAW_SHROUD_MODEL}"
23
+ fi
24
+
25
+ if [ -S "$DAEMON_SOCKET" ]; then
26
+ if command -v 1claw-mcp >/dev/null 2>&1; then
27
+ ONECLAW_LOCAL_VAULT=true ONECLAW_DAEMON_SOCKET="$DAEMON_SOCKET" \
28
+ 1claw-mcp --local 2>/tmp/mcp.log &
29
+ echo "MCP server started in background."
30
+ fi
31
+ fi
32
+
33
+ echo "Ready: http://0.0.0.0:${CHAT_UI_PORT}"
34
+ exec npx tsx agent.ts
@@ -0,0 +1,18 @@
1
+ {
2
+ "name": "1claw-elizaos-agent",
3
+ "version": "1.0.0",
4
+ "private": true,
5
+ "type": "module",
6
+ "scripts": {
7
+ "start": "tsx agent.ts",
8
+ "dev": "tsx watch agent.ts"
9
+ },
10
+ "dependencies": {
11
+ "@elizaos/core": "^0.2.0",
12
+ "@1claw/plugin-elizaos": "latest",
13
+ "@ai-sdk/openai": "^1.0.0",
14
+ "ai": "^4.0.0",
15
+ "tsx": "^4.19.0",
16
+ "typescript": "^5.7.0"
17
+ }
18
+ }
@@ -0,0 +1,25 @@
1
+ name: elizaos
2
+ display_name: "ElizaOS"
3
+ version: 1.0.0
4
+ description: "ElizaOS character runtime with 1Claw vault-backed secrets and signing"
5
+ author: 1Claw
6
+ language: node
7
+ homepage: https://elizaos.ai
8
+
9
+ docker:
10
+ base_image: node:22-slim
11
+ context_files:
12
+ - Dockerfile
13
+ - package.json
14
+ - tsconfig.json
15
+ - agent.ts
16
+ - entrypoint.sh
17
+ env:
18
+ ONECLAW_FRAMEWORK: elizaos
19
+ health_endpoint: /health
20
+ health_port: 3000
21
+
22
+ post_spawn_message: |
23
+ Edit agent.ts to customize your ElizaOS character.
24
+ Your 1Claw MCP server is available at the daemon socket.
25
+ LLM calls are routed through Shroud for inspection and redaction.