diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md
new file mode 100644
index 000000000..acf4d0c60
--- /dev/null
+++ b/.github/PULL_REQUEST_TEMPLATE.md
@@ -0,0 +1,315 @@
+# Pull Request: [Title]
+
+
+
+## ๐ Summary
+
+
+
+## ๐ฏ Related Issues
+
+
+
+Closes #
+
+## ๐ What's New
+
+
+
+### Core Changes
+
+#### 1. [Feature/Component Name]
+
+**Purpose**: [Why this change was made]
+
+**Implementation**:
+
+- Change 1
+- Change 2
+- Change 3
+
+**Key Code** (if applicable):
+
+```javascript
+// Show important code snippets with file paths
+// /path/to/file.js:123-145
+```
+
+## ๐ Type of Change
+
+
+
+- [ ] ๐ Bug fix (non-breaking change that fixes an issue)
+- [ ] โจ New feature (non-breaking change that adds functionality)
+- [ ] ๐ฅ Breaking change (fix or feature that would cause existing functionality to change)
+- [ ] ๐ Documentation update
+- [ ] ๐ง Configuration change
+- [ ] โป๏ธ Code refactoring (no functional changes)
+- [ ] โก Performance improvement
+- [ ] ๐จ UI/UX change
+- [ ] ๐งช Test coverage improvement
+- [ ] ๐ Security fix
+
+## ๐งช Testing
+
+
+
+### Automated Tests
+
+- [ ] Unit tests added/updated
+- [ ] Integration tests added/updated
+- [ ] All existing tests pass
+
+**Test Coverage**:
+
+- [ ] New code has test coverage
+- [ ] Edge cases covered
+- [ ] Error handling tested
+
+**Test Results**:
+
+```bash
+# Include test output or summary
+โ 42 tests passing
+โ 0 tests failing
+```
+
+### Manual Testing
+
+
+
+**Testing Checklist**:
+
+- [ ] Tested in development environment
+- [ ] Tested in staging environment (if applicable)
+- [ ] Tested with real data/production-like scenarios
+- [ ] Tested error scenarios
+- [ ] Verified no console errors/warnings
+- [ ] Checked browser console for issues (frontend changes)
+
+**Environments Tested**:
+
+- [ ] Development
+- [ ] Staging
+- [ ] Production (if safe to test)
+
+## ๐ธ Screenshots/Videos
+
+
+
+### Before
+
+
+
+### After
+
+
+
+## ๐ Deployment Strategy
+
+
+
+### Deployment Steps
+
+1. Step 1
+2. Step 2
+3. Step 3
+
+### Configuration Changes
+
+
+
+- [ ] Environment variables added/updated: `VARIABLE_NAME=value`
+- [ ] Feature flags required: `FEATURE_FLAG=true`
+- [ ] Database migrations needed
+- [ ] External service configuration required
+
+### Phased Rollout (if applicable)
+
+- [ ] **Phase 1**: Deploy to staging for validation (recommended duration: X days)
+- [ ] **Phase 2**: Deploy to production with feature flag disabled
+- [ ] **Phase 3**: Enable feature flag for production traffic
+- [ ] **Phase 4**: Monitor metrics and remove feature flag
+
+## ๐ Rollback Plan
+
+
+
+**Quick Rollback**:
+
+- Disable feature flag: `FEATURE_FLAG=false` and restart service (< 1 minute)
+- OR: Revert to previous deployment revision
+- OR: Git revert commit hash
+
+**Cleanup Required** (if rollback is performed):
+
+- [ ] Database changes to revert
+- [ ] Cache to clear
+- [ ] External services to notify
+
+## ๐ฐ Cost Impact
+
+
+
+**Expected Cost Changes**:
+
+- Cloud Run: +/- $X/month
+- Storage: +/- $X/month
+- API calls: +/- $X/month
+- **Total Estimated Impact**: +/- $X/month
+
+**Cost Optimization Notes**:
+
+- [Explain any cost optimizations included]
+
+## โก Performance Impact
+
+
+
+**Expected Performance Changes**:
+
+- Response time: +/- Xms
+- Memory usage: +/- XMB
+- Database queries: +/- X queries
+- API calls: +/- X calls
+
+**Benchmarks** (if applicable):
+
+```text
+Before: Xms average response time
+After: Xms average response time
+```
+
+## ๐ Code Quality
+
+
+
+- [x] ESLint passed (auto-checked by pre-commit hooks)
+- [x] Prettier formatting applied (auto-checked by pre-commit hooks)
+- [x] Markdownlint passed for docs (auto-checked by pre-commit hooks)
+- [x] Commit messages follow conventional commits
+- [ ] Code reviewed by AI agent or peer
+- [ ] No console.log statements in production code
+- [ ] No commented-out code left behind
+- [ ] Error handling implemented for edge cases
+- [ ] Security considerations reviewed (XSS, SQL injection, auth, etc.)
+
+## ๐ Documentation
+
+
+
+- [ ] README.md updated (if user-facing changes)
+- [ ] CONTRIBUTING.md updated (if dev workflow changes)
+- [ ] API documentation updated (if API changes)
+- [ ] Inline code comments added for complex logic
+- [ ] Architecture documentation updated (if structural changes)
+- [ ] CLAUDE.md updated (for AI context in future sessions)
+
+## ๐ Security Considerations
+
+
+
+- [ ] No sensitive data logged or exposed
+- [ ] Authentication/authorization implemented correctly
+- [ ] Input validation added for user input
+- [ ] SQL injection prevention (parameterized queries)
+- [ ] XSS prevention (sanitized output)
+- [ ] CSRF protection (if applicable)
+- [ ] Secrets stored securely (not in code/logs)
+- [ ] Rate limiting considered (if applicable)
+
+## ๐ Pre-Merge Checklist
+
+
+
+- [ ] All tests pass locally
+- [ ] All pre-commit hooks pass
+- [ ] Code has been self-reviewed
+- [ ] Changes generate no new warnings
+- [ ] Dependent changes have been merged
+- [ ] Documentation has been updated
+- [ ] Reviewer(s) have approved the PR
+- [ ] Branch is up to date with base branch
+- [ ] Commit messages are clean and descriptive
+- [ ] Ready for production deployment
+
+## ๐ Additional Context
+
+
+
+## ๐ฆ Status
+
+
+
+- [ ] ๐ด Draft - Work in progress
+- [ ] ๐ก Ready for Review - Code complete, needs review
+- [ ] ๐ข Approved - Ready to merge
+- [ ] ๐ต Merged - Deployed to staging
+- [ ] โ
Complete - Deployed to production
+
+---
+
+
diff --git a/src/agents/system-prompt.ts b/src/agents/system-prompt.ts
index ed97fd539..9624fdb2d 100644
--- a/src/agents/system-prompt.ts
+++ b/src/agents/system-prompt.ts
@@ -83,21 +83,21 @@ function buildMessagingSection(params: {
"- Never use exec/curl for provider messaging; Moltbot handles all routing internally.",
params.availableTools.has("message")
? [
- "",
- "### message tool",
- "- Use `message` for proactive sends + channel actions (polls, reactions, etc.).",
- "- For `action=send`, include `to` and `message`.",
- `- If multiple channels are configured, pass \`channel\` (${params.messageChannelOptions}).`,
- `- If you use \`message\` (\`action=send\`) to deliver your user-visible reply, respond with ONLY: ${SILENT_REPLY_TOKEN} (avoid duplicate replies).`,
- params.inlineButtonsEnabled
- ? "- Inline buttons supported. Use `action=send` with `buttons=[[{text,callback_data}]]` (callback_data routes back as a user message)."
- : params.runtimeChannel
- ? `- Inline buttons not enabled for ${params.runtimeChannel}. If you need them, ask to set ${params.runtimeChannel}.capabilities.inlineButtons ("dm"|"group"|"all"|"allowlist").`
- : "",
- ...(params.messageToolHints ?? []),
- ]
- .filter(Boolean)
- .join("\n")
+ "",
+ "### message tool",
+ "- Use `message` for proactive sends + channel actions (polls, reactions, etc.).",
+ "- For `action=send`, include `to` and `message`.",
+ `- If multiple channels are configured, pass \`channel\` (${params.messageChannelOptions}).`,
+ `- If you use \`message\` (\`action=send\`) to deliver your user-visible reply, respond with ONLY: ${SILENT_REPLY_TOKEN} (avoid duplicate replies).`,
+ params.inlineButtonsEnabled
+ ? "- Inline buttons supported. Use `action=send` with `buttons=[[{text,callback_data}]]` (callback_data routes back as a user message)."
+ : params.runtimeChannel
+ ? `- Inline buttons not enabled for ${params.runtimeChannel}. If you need them, ask to set ${params.runtimeChannel}.capabilities.inlineButtons ("dm"|"group"|"all"|"allowlist").`
+ : "",
+ ...(params.messageToolHints ?? []),
+ ]
+ .filter(Boolean)
+ .join("\n")
: "",
"",
];
@@ -282,15 +282,15 @@ export function buildAgentSystemPrompt(params: {
: undefined;
const reasoningHint = params.reasoningTagHint
? [
- "ALL internal reasoning MUST be inside ....",
- "Do not output any analysis outside .",
- "Format every reply as ... then ..., with no other text.",
- "Only the final user-visible reply may appear inside .",
- "Only text inside is shown to the user; everything else is discarded and never seen by the user.",
- "Example:",
- "Short internal reasoning.",
- "Hey there! What would you like to do next?",
- ].join(" ")
+ "ALL internal reasoning MUST be inside ....",
+ "Do not output any analysis outside .",
+ "Format every reply as ... then ..., with no other text.",
+ "Only the final user-visible reply may appear inside .",
+ "Only text inside is shown to the user; everything else is discarded and never seen by the user.",
+ "Example:",
+ "Short internal reasoning.",
+ "Hey there! What would you like to do next?",
+ ].join(" ")
: undefined;
const reasoningLevel = params.reasoningLevel ?? "off";
const userTimezone = params.userTimezone?.trim();
@@ -336,21 +336,21 @@ export function buildAgentSystemPrompt(params: {
toolLines.length > 0
? toolLines.join("\n")
: [
- "Pi lists the standard tools above. This runtime enables:",
- "- grep: search file contents for patterns",
- "- find: find files by glob pattern",
- "- ls: list directory contents",
- "- apply_patch: apply multi-file patches",
- `- ${execToolName}: run shell commands (supports background via yieldMs/background)`,
- `- ${processToolName}: manage background exec sessions`,
- "- browser: control clawd's dedicated browser",
- "- canvas: present/eval/snapshot the Canvas",
- "- nodes: list/describe/notify/camera/screen on paired nodes",
- "- cron: manage cron jobs and wake events (use for reminders; when scheduling a reminder, write the systemEvent text as something that will read like a reminder when it fires, and mention that it is a reminder depending on the time gap between setting and firing; include recent context in reminder text if appropriate)",
- "- sessions_list: list sessions",
- "- sessions_history: fetch session history",
- "- sessions_send: send to another session",
- ].join("\n"),
+ "Pi lists the standard tools above. This runtime enables:",
+ "- grep: search file contents for patterns",
+ "- find: find files by glob pattern",
+ "- ls: list directory contents",
+ "- apply_patch: apply multi-file patches",
+ `- ${execToolName}: run shell commands (supports background via yieldMs/background)`,
+ `- ${processToolName}: manage background exec sessions`,
+ "- browser: control clawd's dedicated browser",
+ "- canvas: present/eval/snapshot the Canvas",
+ "- nodes: list/describe/notify/camera/screen on paired nodes",
+ "- cron: manage cron jobs and wake events (use for reminders; when scheduling a reminder, write the systemEvent text as something that will read like a reminder when it fires, and mention that it is a reminder depending on the time gap between setting and firing; include recent context in reminder text if appropriate)",
+ "- sessions_list: list sessions",
+ "- sessions_history: fetch session history",
+ "- sessions_send: send to another session",
+ ].join("\n"),
"TOOLS.md does not control tool availability; it is user guidance for how to use external tools.",
"If a task is more complex or takes longer, spawn a sub-agent. It will do the work for you and ping you when it's done. You can always check up on it.",
"",
@@ -375,11 +375,11 @@ export function buildAgentSystemPrompt(params: {
hasGateway && !isMinimal ? "## Moltbot Self-Update" : "",
hasGateway && !isMinimal
? [
- "Get Updates (self-update) is ONLY allowed when the user explicitly asks for it.",
- "Do not run config.apply or update.run unless the user explicitly requests an update or config change; if it's not explicit, ask first.",
- "Actions: config.get, config.schema, config.apply (validate + write full config, then restart), update.run (update deps or git, then restart).",
- "After restart, Moltbot pings the last active session automatically.",
- ].join("\n")
+ "Get Updates (self-update) is ONLY allowed when the user explicitly asks for it.",
+ "Do not run config.apply or update.run unless the user explicitly requests an update or config change; if it's not explicit, ask first.",
+ "Actions: config.get, config.schema, config.apply (validate + write full config, then restart), update.run (update deps or git, then restart).",
+ "After restart, Moltbot pings the last active session automatically.",
+ ].join("\n")
: "",
hasGateway && !isMinimal ? "" : "",
"",
@@ -399,47 +399,57 @@ export function buildAgentSystemPrompt(params: {
"Treat this directory as the single global workspace for file operations unless explicitly instructed otherwise.",
...workspaceNotes,
"",
+ ...(runtimeInfo?.os?.toLowerCase().includes("windows")
+ ? [
+ "## Windows Shell Guidance",
+ "You are running on Windows (PowerShell).",
+ "- Use PowerShell syntax (e.g. `$env:VAR` instead of `%VAR%` or `$VAR`).",
+ "- Do NOT use Unix commands like `grep`, `sed`, `awk`, `head`, `tail` unless you are sure they are installed.",
+ "- Use `findstr` or `Select-String` instead of `grep`.",
+ "- Use `Get-ChildItem` (dir/ls) with `-Recurse` instead of `find`.",
+ "",
+ ]
+ : []),
...docsSection,
params.sandboxInfo?.enabled ? "## Sandbox" : "",
params.sandboxInfo?.enabled
? [
- "You are running in a sandboxed runtime (tools execute in Docker).",
- "Some tools may be unavailable due to sandbox policy.",
- "Sub-agents stay sandboxed (no elevated/host access). Need outside-sandbox read/write? Don't spawn; ask first.",
- params.sandboxInfo.workspaceDir
- ? `Sandbox workspace: ${params.sandboxInfo.workspaceDir}`
+ "You are running in a sandboxed runtime (tools execute in Docker).",
+ "Some tools may be unavailable due to sandbox policy.",
+ "Sub-agents stay sandboxed (no elevated/host access). Need outside-sandbox read/write? Don't spawn; ask first.",
+ params.sandboxInfo.workspaceDir
+ ? `Sandbox workspace: ${params.sandboxInfo.workspaceDir}`
+ : "",
+ params.sandboxInfo.workspaceAccess
+ ? `Agent workspace access: ${params.sandboxInfo.workspaceAccess}${params.sandboxInfo.agentWorkspaceMount
+ ? ` (mounted at ${params.sandboxInfo.agentWorkspaceMount})`
+ : ""
+ }`
+ : "",
+ params.sandboxInfo.browserBridgeUrl ? "Sandbox browser: enabled." : "",
+ params.sandboxInfo.browserNoVncUrl
+ ? `Sandbox browser observer (noVNC): ${params.sandboxInfo.browserNoVncUrl}`
+ : "",
+ params.sandboxInfo.hostBrowserAllowed === true
+ ? "Host browser control: allowed."
+ : params.sandboxInfo.hostBrowserAllowed === false
+ ? "Host browser control: blocked."
: "",
- params.sandboxInfo.workspaceAccess
- ? `Agent workspace access: ${params.sandboxInfo.workspaceAccess}${
- params.sandboxInfo.agentWorkspaceMount
- ? ` (mounted at ${params.sandboxInfo.agentWorkspaceMount})`
- : ""
- }`
- : "",
- params.sandboxInfo.browserBridgeUrl ? "Sandbox browser: enabled." : "",
- params.sandboxInfo.browserNoVncUrl
- ? `Sandbox browser observer (noVNC): ${params.sandboxInfo.browserNoVncUrl}`
- : "",
- params.sandboxInfo.hostBrowserAllowed === true
- ? "Host browser control: allowed."
- : params.sandboxInfo.hostBrowserAllowed === false
- ? "Host browser control: blocked."
- : "",
- params.sandboxInfo.elevated?.allowed
- ? "Elevated exec is available for this session."
- : "",
- params.sandboxInfo.elevated?.allowed
- ? "User can toggle with /elevated on|off|ask|full."
- : "",
- params.sandboxInfo.elevated?.allowed
- ? "You may also send /elevated on|off|ask|full when needed."
- : "",
- params.sandboxInfo.elevated?.allowed
- ? `Current elevated level: ${params.sandboxInfo.elevated.defaultLevel} (ask runs exec on host with approvals; full auto-approves).`
- : "",
- ]
- .filter(Boolean)
- .join("\n")
+ params.sandboxInfo.elevated?.allowed
+ ? "Elevated exec is available for this session."
+ : "",
+ params.sandboxInfo.elevated?.allowed
+ ? "User can toggle with /elevated on|off|ask|full."
+ : "",
+ params.sandboxInfo.elevated?.allowed
+ ? "You may also send /elevated on|off|ask|full when needed."
+ : "",
+ params.sandboxInfo.elevated?.allowed
+ ? `Current elevated level: ${params.sandboxInfo.elevated.defaultLevel} (ask runs exec on host with approvals; full auto-approves).`
+ : "",
+ ]
+ .filter(Boolean)
+ .join("\n")
: "",
params.sandboxInfo?.enabled ? "" : "",
...buildUserIdentitySection(ownerLine, isMinimal),
@@ -472,22 +482,22 @@ export function buildAgentSystemPrompt(params: {
const guidanceText =
level === "minimal"
? [
- `Reactions are enabled for ${channel} in MINIMAL mode.`,
- "React ONLY when truly relevant:",
- "- Acknowledge important user requests or confirmations",
- "- Express genuine sentiment (humor, appreciation) sparingly",
- "- Avoid reacting to routine messages or your own replies",
- "Guideline: at most 1 reaction per 5-10 exchanges.",
- ].join("\n")
+ `Reactions are enabled for ${channel} in MINIMAL mode.`,
+ "React ONLY when truly relevant:",
+ "- Acknowledge important user requests or confirmations",
+ "- Express genuine sentiment (humor, appreciation) sparingly",
+ "- Avoid reacting to routine messages or your own replies",
+ "Guideline: at most 1 reaction per 5-10 exchanges.",
+ ].join("\n")
: [
- `Reactions are enabled for ${channel} in EXTENSIVE mode.`,
- "Feel free to react liberally:",
- "- Acknowledge messages with appropriate emojis",
- "- Express sentiment and personality through reactions",
- "- React to interesting content, humor, or notable events",
- "- Use reactions to confirm understanding or agreement",
- "Guideline: react whenever it feels natural.",
- ].join("\n");
+ `Reactions are enabled for ${channel} in EXTENSIVE mode.`,
+ "Feel free to react liberally:",
+ "- Acknowledge messages with appropriate emojis",
+ "- Express sentiment and personality through reactions",
+ "- React to interesting content, humor, or notable events",
+ "- Use reactions to confirm understanding or agreement",
+ "Guideline: react whenever it feels natural.",
+ ].join("\n");
lines.push("## Reactions", guidanceText, "");
}
if (reasoningHint) {