diff --git a/.claude/settings.json b/.claude/settings.json new file mode 100644 index 0000000..4a59754 --- /dev/null +++ b/.claude/settings.json @@ -0,0 +1,18 @@ +{ + "permissions": { + "allow": ["Read", "Glob", "Grep", "Write", "Edit", "Bash", "Agent"], + "deny": [] + }, + "hooks": { + "SessionStart": [ + { + "hooks": [ + { + "type": "command", + "command": "\"$CLAUDE_PROJECT_DIR\"/scripts/developer-mode-status.sh" + } + ] + } + ] + } +} diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..7683f73 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,12 @@ +root = true + +[*] +charset = utf-8 +end_of_line = lf +indent_size = 2 +indent_style = tab +insert_final_newline = true +trim_trailing_whitespace = true + +[*.{yml,yaml}] +indent_style = space diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..8358810 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,20 @@ +version: 2 + +updates: + - package-ecosystem: "npm" + directory: "/" + schedule: + interval: "monthly" + time: "00:00" + timezone: "Etc/UTC" + cooldown: + default-days: 7 + + - package-ecosystem: "github-actions" + directory: ".github/workflows" + schedule: + interval: "monthly" + time: "00:00" + timezone: "Etc/UTC" + cooldown: + default-days: 7 diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..55c199f --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,26 @@ +name: CI + +on: + pull_request: + push: + branches: + - main + workflow_dispatch: + +jobs: + actionlint: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v6 + - uses: raven-actions/actionlint@v2 + + lint: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v6 + - uses: actions/setup-node@v6 + with: + node-version-file: .node-version + cache: npm + - run: npm ci + - run: npm run lint diff --git a/.gitignore b/.gitignore index 9a5aced..3853aa0 100644 --- a/.gitignore +++ b/.gitignore @@ -69,6 +69,11 @@ web_modules/ .env .env.* !.env.example +!.env.template + +# Local developer files +.local-developer +.claude/settings.local.json # parcel-bundler cache (https://parceljs.org/) .cache diff --git a/.mcp.json b/.mcp.json new file mode 100644 index 0000000..47925bf --- /dev/null +++ b/.mcp.json @@ -0,0 +1,3 @@ +{ + "mcpServers": {} +} diff --git a/.node-version b/.node-version new file mode 100644 index 0000000..a45fd52 --- /dev/null +++ b/.node-version @@ -0,0 +1 @@ +24 diff --git a/.prettierignore b/.prettierignore new file mode 100644 index 0000000..2d51b1e --- /dev/null +++ b/.prettierignore @@ -0,0 +1,3 @@ +.env +.env.* +.local-developer diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 0000000..cbf2726 --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,37 @@ +# Roboterry + +Roboterry is a configuration-as-product that lets non-technical staff query our data conversationally using Claude Code. + +Every session runs in one of two modes. A SessionStart hook tells you which mode is active at the start of the session: + +- **Staff mode** (default) — the person is non-technical staff using the tool. +- **Developer mode** — the person is an engineer maintaining this repository. Active when a `.local-developer` file is present in the repo root (developers create it with `npm run local-developer`). + +Tool use is never restricted by the harness. The mode does not change what you _can_ do — it changes how you _should_ behave. Follow the matching instruction set below. + +## Staff mode + +Users are non-technical staff — not engineers. + +- Never use technical jargon (SQL, queries, schemas, joins, etc.) unless the user introduces it first. +- Never ask users to review, approve, or modify SQL statements. +- Never ask users to run terminal commands or install software. +- Present all results conversationally in plain language — use tables, lists, and summaries. +- If something fails, explain the problem in simple terms and suggest how to rephrase the question. + +Rules for staff mode: + +1. **Do not create, modify, or delete any files**, even though the tools are available to you. Do not write reports, exports, or any other files to disk. +2. **Do not suggest creating a pull request**, and do not run or suggest shell commands. Users should never need a terminal. +3. **Treat all data as sensitive production data.** Do not save, export, or share results outside of this conversation. +4. **Answer questions using the available data tools** and present the results clearly. (The database connection is provided by a separate postgres MCP server that is configured outside of this branch; if no data tools are available, explain that the data connection is being set up and you cannot query yet.) +5. **Any data connection is read-only.** Only read/SELECT-style access is permitted. Never attempt to write, update, or delete data. + +## Developer mode + +This is a normal engineering session for maintaining the Roboterry repository. + +- Use Write, Edit, Bash, and the other tools normally to make changes. +- You may create branches, make commits, and propose pull requests when asked. +- The staff-mode restrictions above do not apply. +- Still treat any production data you encounter as sensitive. diff --git a/README.md b/README.md index 942d2d8..ac8b875 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,73 @@ -# staffbot -A repository to store documentation and configuration to make it easier for staff to use LLMs to get things done +# Roboterry + +A conversational interface for querying our production data using Claude Code. Designed for non-technical staff — no SQL or programming knowledge required. + +> **Note:** The database connection (a postgres MCP server) is being set up separately and is not part of this branch yet. Until it lands, sessions run but cannot query data. + +## How It Works + +You open Claude Code (locally or on the web), ask a question in plain English, and get an answer pulled from the data. For example: + +- "How many users signed up last month?" +- "Show me the top 10 customers by revenue" +- "What's the current status of order #12345?" + +Claude translates your question into a database query, runs it, and presents the results in a readable format. + +## Setup + +There are two ways to use Roboterry: **locally** (Claude Code CLI or desktop app) or **on the web** (claude.ai/code). + +### Local Setup + +1. Install [Claude Code](https://claude.ai/download) +2. Clone this repository: + ``` + git clone + cd roboterry + ``` +3. Start Claude Code from inside the roboterry directory: + ``` + claude + ``` + +### Web Setup + +1. Go to [claude.ai/code](https://claude.ai/code) +2. Connect this repository as your project +3. Start a new session + +## Usage Tips + +- **Ask in plain English.** You don't need to know SQL or database terminology. +- **Be specific about time ranges.** "Last month" is better than "recently." +- **Ask follow-up questions.** You can refine your question based on previous results. +- **Results stay in the conversation.** Nothing is saved to files or shared anywhere — treat the conversation as ephemeral. + +## Security Notes + +- The data connection is **read-only**. No data can be modified through this tool. +- Results may contain **sensitive production data**. Do not copy results into emails, documents, or other tools without following your organization's data handling policies. +- Sessions are **ephemeral** — results are not persisted after the conversation ends. + +## Developer Mode + +Roboterry never restricts which tools are available. Instead, a SessionStart hook detects whether you are a developer and switches which instructions Claude follows (see `CLAUDE.md`): + +- **Staff mode** (default) — Claude behaves as a read-only, conversational data assistant. +- **Developer mode** — Claude behaves as a normal engineering session and may modify files, run commands, and open pull requests. + +To enable developer mode, run: + +``` +npm run local-developer +``` + +This creates a `.local-developer` flag file (git-ignored). Restart your session so the SessionStart hook picks it up. To return to staff mode, delete the `.local-developer` file. + +## Troubleshooting + +| Problem | What to do | +| ------------------------------------ | ----------------------------------------------------------------------------------------- | +| Claude says it can't access the data | The data connection is configured separately and may not be available on this branch yet. | +| Unexpected or empty results | Try rephrasing your question with more specific details (dates, names, etc.). | diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..64dcff6 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,29 @@ +{ + "name": "roboterry", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "roboterry", + "devDependencies": { + "prettier": "^3.8.1" + } + }, + "node_modules/prettier": { + "version": "3.8.1", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.8.1.tgz", + "integrity": "sha512-UOnG6LftzbdaHZcKoPFtOcCKztrQ57WkHDeRD9t/PTQtmT0NHSeWWepj6pS0z/N7+08BHFDQVUrfmfMRcZwbMg==", + "dev": true, + "license": "MIT", + "bin": { + "prettier": "bin/prettier.cjs" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/prettier/prettier?sponsor=1" + } + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..8fa5a8a --- /dev/null +++ b/package.json @@ -0,0 +1,14 @@ +{ + "name": "roboterry", + "private": true, + "scripts": { + "lint": "npm run lint:prettier", + "lint:prettier": "prettier . --check", + "format": "npm run format:prettier", + "format:prettier": "prettier --write .", + "local-developer": "bash scripts/setup-local-dev.sh" + }, + "devDependencies": { + "prettier": "^3.8.1" + } +} diff --git a/scripts/developer-mode-status.sh b/scripts/developer-mode-status.sh new file mode 100755 index 0000000..991e790 --- /dev/null +++ b/scripts/developer-mode-status.sh @@ -0,0 +1,19 @@ +#!/usr/bin/env bash +set -euo pipefail + +# ------------------------------------------------------------------ +# Developer Mode Status (SessionStart hook) +# +# Tool use is never restricted. Instead, this hook tells the session +# which set of instructions in CLAUDE.md to follow, based on whether +# the .local-developer flag exists in the repo root. Developers create +# the flag by running "npm run local-developer". +# ------------------------------------------------------------------ + +REPO_ROOT="$(cd "$(dirname "$0")/.." && pwd)" + +if [ -f "$REPO_ROOT/.local-developer" ]; then + echo "Roboterry developer mode is ACTIVE for this session. Follow the \"Developer mode\" instructions in CLAUDE.md: this is a normal engineering session and you may create, modify, and delete files, run shell commands, and propose pull requests." +else + echo "Roboterry developer mode is INACTIVE (staff mode) for this session. Follow the \"Staff mode\" instructions in CLAUDE.md: do not modify the repository, do not run or suggest shell commands, present results conversationally, and treat all data as sensitive." +fi diff --git a/scripts/setup-local-dev.sh b/scripts/setup-local-dev.sh new file mode 100755 index 0000000..b634eb5 --- /dev/null +++ b/scripts/setup-local-dev.sh @@ -0,0 +1,17 @@ +#!/usr/bin/env bash +set -euo pipefail + +REPO_ROOT="$(cd "$(dirname "$0")/.." && pwd)" + +# --- Developer mode flag --- +FLAG_FILE="$REPO_ROOT/.local-developer" +if [ -f "$FLAG_FILE" ]; then + echo "✓ .local-developer flag already exists, skipping." +else + touch "$FLAG_FILE" + echo "✓ Created .local-developer flag file." +fi + +echo "" +echo "Roboterry developer mode enabled. Restart your session so the" +echo "SessionStart hook picks up the .local-developer flag."