@autoship/react 0.3.0 → 0.5.0

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.
package/README.md ADDED
@@ -0,0 +1,178 @@
1
+ # Autoship
2
+
3
+ A drop-in autonomous coding agent that records tasks in your app and implements them in a Github Action.
4
+
5
+ ## How It Works
6
+
7
+ 1. Users submit tasks via React components (or directly via Supabase)
8
+ 2. A GitHub Action wakes up periodically and runs Claude Code
9
+ 3. Claude picks up the highest priority task, implements it, and creates a PR
10
+ 4. If Claude needs clarification, it asks a question and blocks the task until you answer
11
+ 5. You review the PR and merge
12
+
13
+ ## Packages
14
+
15
+ - **`@autoship/react`** - React components and CLI for task submission
16
+ - **`mcp-servers/autoship-mcp`** - MCP server for Claude Code integration
17
+
18
+ ## Quick Start
19
+
20
+ ### 1. Create Supabase Project
21
+
22
+ Create a new Supabase project (or use an existing one). Get the SUPABASE_URL and your database password.
23
+
24
+ ### 2. Set Up Supabase Database
25
+
26
+ Run the migrations using the CLI:
27
+
28
+ ```bash
29
+ npx @autoship init
30
+ ```
31
+
32
+ The CLI will prompt you for credentials. You can provide them in two ways:
33
+
34
+ **Option A: Full DATABASE_URL**
35
+
36
+ ```bash
37
+ # Find this in Supabase Dashboard > Project Settings > Database > Connection string > URI
38
+ npx @autoship init --database-url "postgresql://postgres.xxx:password@aws-0-region.pooler.supabase.com:6543/postgres"
39
+ ```
40
+
41
+ **Option B: Supabase URL + Database Password**
42
+
43
+ ```bash
44
+ npx @autoship init --supabase-url https://xxx.supabase.co --db-password yourpassword
45
+ ```
46
+
47
+ **Using environment variables:**
48
+
49
+ ```bash
50
+ # Option A
51
+ DATABASE_URL="postgresql://..." npx @autoship init
52
+
53
+ # Option B
54
+ SUPABASE_URL="https://xxx.supabase.co" DB_PASSWORD="yourpassword" npx @autoship/react init
55
+ ```
56
+
57
+ ### 3. Expose the Autoship Schema in Supabase
58
+
59
+ Autoship uses a dedicated `autoship` database schema to avoid conflicts with your existing tables. You need to expose this schema via the Supabase API:
60
+
61
+ 1. Go to your Supabase project dashboard
62
+ 2. Navigate to **Project Settings** (gear icon) → **API**
63
+ 3. Scroll down to **Data API Settings**
64
+ 4. Find **Extra search path** and add `autoship` to the list
65
+ 5. Save the changes
66
+
67
+ This allows the Supabase client to access the `autoship` schema via the REST API.
68
+
69
+ ### 4. Add React Components (Optional)
70
+
71
+ Install the package:
72
+
73
+ ```bash
74
+ npm install @autoship/react
75
+ ```
76
+
77
+ Add the provider and button to your app:
78
+
79
+ ```tsx
80
+ import { AutoshipProvider, AutoshipButton } from "@autoship/react";
81
+
82
+ function App() {
83
+ return (
84
+ <AutoshipProvider
85
+ supabaseUrl={process.env.SUPABASE_URL}
86
+ supabaseAnonKey={process.env.SUPABASE_ANON_KEY}
87
+ userId="optional-user-id"
88
+ >
89
+ <YourApp />
90
+ <AutoshipButton />
91
+ </AutoshipProvider>
92
+ );
93
+ }
94
+ ```
95
+
96
+ Available components:
97
+
98
+ - `AutoshipProvider` - Context provider for Supabase connection
99
+ - `AutoshipButton` - Floating button to open task submission dialog
100
+ - `TaskDialog` - Modal for submitting new tasks
101
+ - `TaskList` - List of submitted tasks with status
102
+ - `TaskDetailDialog` - View task details and answer questions
103
+ - `QuestionDialog` - Answer clarifying questions from Claude
104
+
105
+ ### 5. Set Up GitHub Action
106
+
107
+ Copy these files into your project:
108
+
109
+ ```
110
+ mcp-servers/autoship-mcp/ # The MCP server
111
+ .mcp.json # MCP configuration
112
+ .github/workflows/claude-agent.yml # GitHub Actions workflow
113
+ ```
114
+
115
+ Add GitHub Secrets (Settings > Secrets and variables > Actions):
116
+
117
+ | Secret | Description |
118
+ | ---------------------- | ----------------------------------------------------------- |
119
+ | `ANTHROPIC_API_KEY` | Your Anthropic API key |
120
+ | `SUPABASE_URL` | Your Supabase project URL (e.g., `https://xxx.supabase.co`) |
121
+ | `SUPABASE_SERVICE_KEY` | Supabase service role key (not the anon key) |
122
+
123
+ ### 6. Test Locally (Optional)
124
+
125
+ Build the MCP server:
126
+
127
+ ```bash
128
+ cd mcp-servers/autoship-mcp && npm install && npm run build
129
+ ```
130
+
131
+ ```bash
132
+ # Set environment variables
133
+ export SUPABASE_URL="https://your-project.supabase.co"
134
+ export SUPABASE_SERVICE_KEY="your-service-key"
135
+
136
+ # Test the MCP tools
137
+ claude "Use the autoship-mcp tools to list pending tasks"
138
+ ```
139
+
140
+ ## Manual Trigger
141
+
142
+ You can manually trigger the agent from the GitHub Actions tab, optionally with a custom prompt:
143
+
144
+ 1. Go to Actions > Claude Agent
145
+ 2. Click "Run workflow"
146
+ 3. Optionally enter a custom prompt
147
+ 4. Click "Run workflow"
148
+
149
+ ## Monitoring
150
+
151
+ ### GitHub Actions Logs
152
+
153
+ Check the Actions tab in your repository to see Claude's output for each run.
154
+
155
+ ## Available MCP Tools
156
+
157
+ | Tool | Description |
158
+ | -------------------------- | ---------------------------------------------------- |
159
+ | `list_pending_tasks` | List all pending tasks by priority |
160
+ | `get_task` | Get full details including categories and questions |
161
+ | `claim_task` | Mark a task as in_progress |
162
+ | `complete_task` | Mark as complete with branch name |
163
+ | `fail_task` | Mark as failed with error message |
164
+ | `add_task` | Create new tasks |
165
+ | `list_categories` | List all categories |
166
+ | `create_category` | Create a new category |
167
+ | `assign_category` | Tag a task with a category |
168
+ | `ask_question` | Ask a clarifying question (marks task as needs_info) |
169
+ | `get_unanswered_questions` | List all unanswered questions |
170
+ | `check_answered_questions` | Check answers for a specific task |
171
+ | `resume_task` | Move a needs_info task back to pending |
172
+
173
+ ## Cost Estimation
174
+
175
+ - Each run uses API tokens based on context length and task complexity
176
+ - A typical task costs $0.10-$1.00
177
+ - With 4 runs/day, expect ~$10-30/month (varies by task complexity)
178
+ - Monitor usage at console.anthropic.com
@@ -1,8 +1,14 @@
1
1
  import { SupabaseClient } from "@supabase/supabase-js";
2
2
  import React from "react";
3
+ /**
4
+ * The database schema used by Autoship.
5
+ * All tables are created in this schema to avoid conflicts with other schemas.
6
+ */
7
+ export declare const AUTOSHIP_SCHEMA = "autoship";
3
8
  export interface AutoshipContextValue {
4
- supabase: SupabaseClient;
9
+ supabase: SupabaseClient<any, typeof AUTOSHIP_SCHEMA>;
5
10
  userId?: string;
11
+ schema: string;
6
12
  }
7
13
  export declare function useAutoshipContext(): AutoshipContextValue;
8
14
  export interface AutoshipProviderProps {
@@ -1 +1 @@
1
- {"version":3,"file":"AutoshipProvider.d.ts","sourceRoot":"","sources":["../src/AutoshipProvider.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAgB,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACrE,OAAO,KAA6C,MAAM,OAAO,CAAC;AAElE,MAAM,WAAW,oBAAoB;IACnC,QAAQ,EAAE,cAAc,CAAC;IACzB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAID,wBAAgB,kBAAkB,IAAI,oBAAoB,CAMzD;AAED,MAAM,WAAW,qBAAqB;IACpC,WAAW,EAAE,MAAM,CAAC;IACpB,eAAe,EAAE,MAAM,CAAC;IACxB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;CAC3B;AAED,wBAAgB,gBAAgB,CAAC,EAC/B,WAAW,EACX,eAAe,EACf,MAAM,EACN,QAAQ,GACT,EAAE,qBAAqB,GAAG,KAAK,CAAC,YAAY,CAW5C"}
1
+ {"version":3,"file":"AutoshipProvider.d.ts","sourceRoot":"","sources":["../src/AutoshipProvider.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAgB,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACrE,OAAO,KAA6C,MAAM,OAAO,CAAC;AAElE;;;GAGG;AACH,eAAO,MAAM,eAAe,aAAa,CAAC;AAE1C,MAAM,WAAW,oBAAoB;IACnC,QAAQ,EAAE,cAAc,CAAC,GAAG,EAAE,OAAO,eAAe,CAAC,CAAC;IACtD,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;CAChB;AAID,wBAAgB,kBAAkB,IAAI,oBAAoB,CAMzD;AAED,MAAM,WAAW,qBAAqB;IACpC,WAAW,EAAE,MAAM,CAAC;IACpB,eAAe,EAAE,MAAM,CAAC;IACxB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;CAC3B;AAED,wBAAgB,gBAAgB,CAAC,EAC/B,WAAW,EACX,eAAe,EACf,MAAM,EACN,QAAQ,GACT,EAAE,qBAAqB,GAAG,KAAK,CAAC,YAAY,CAe5C"}
@@ -1,6 +1,11 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
2
  import { createClient } from "@supabase/supabase-js";
3
3
  import { createContext, useContext, useMemo } from "react";
4
+ /**
5
+ * The database schema used by Autoship.
6
+ * All tables are created in this schema to avoid conflicts with other schemas.
7
+ */
8
+ export const AUTOSHIP_SCHEMA = "autoship";
4
9
  const AutoshipContext = createContext(null);
5
10
  export function useAutoshipContext() {
6
11
  const ctx = useContext(AutoshipContext);
@@ -10,6 +15,10 @@ export function useAutoshipContext() {
10
15
  return ctx;
11
16
  }
12
17
  export function AutoshipProvider({ supabaseUrl, supabaseAnonKey, userId, children, }) {
13
- const supabase = useMemo(() => createClient(supabaseUrl, supabaseAnonKey), [supabaseUrl, supabaseAnonKey]);
14
- return (_jsx(AutoshipContext.Provider, { value: { supabase, userId }, children: children }));
18
+ const supabase = useMemo(() => createClient(supabaseUrl, supabaseAnonKey, {
19
+ db: {
20
+ schema: AUTOSHIP_SCHEMA,
21
+ },
22
+ }), [supabaseUrl, supabaseAnonKey]);
23
+ return (_jsx(AutoshipContext.Provider, { value: { supabase, userId, schema: AUTOSHIP_SCHEMA }, children: children }));
15
24
  }
@@ -1 +1 @@
1
- {"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../src/cli/init.ts"],"names":[],"mappings":"AA6WA,wBAAsB,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAcvD"}
1
+ {"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../src/cli/init.ts"],"names":[],"mappings":"AAkXA,wBAAsB,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAcvD"}
package/dist/cli/init.js CHANGED
@@ -1,6 +1,6 @@
1
- import postgres from "postgres";
2
1
  import * as fs from "fs";
3
2
  import * as path from "path";
3
+ import postgres from "postgres";
4
4
  import * as readline from "readline";
5
5
  import { fileURLToPath } from "url";
6
6
  const __filename = fileURLToPath(import.meta.url);
@@ -250,16 +250,21 @@ async function runMigration(databaseUrl, migrationSql) {
250
250
  let allTablesExist = true;
251
251
  for (const table of tables) {
252
252
  try {
253
- await sql.unsafe(`SELECT 1 FROM ${table} LIMIT 0`);
254
- console.log(` [x] ${table}`);
253
+ await sql.unsafe(`SELECT 1 FROM autoship.${table} LIMIT 0`);
254
+ console.log(` [x] autoship.${table}`);
255
255
  }
256
256
  catch (error) {
257
- console.log(` [ ] ${table} - NOT FOUND`);
257
+ console.log(` [ ] autoship.${table} - NOT FOUND`);
258
258
  allTablesExist = false;
259
259
  }
260
260
  }
261
261
  if (allTablesExist) {
262
- console.log("\n All tables created. Your database is ready!\n");
262
+ console.log("\n All tables created in the 'autoship' schema.\n");
263
+ console.log(" IMPORTANT: Expose the schema in Supabase Dashboard:");
264
+ console.log(" 1. Go to Project Settings > API");
265
+ console.log(" 2. Scroll to 'Data API Settings'");
266
+ console.log(" 3. Add 'autoship' to the 'Extra search path'");
267
+ console.log(" 4. Save changes\n");
263
268
  console.log(" Next steps:");
264
269
  console.log(" 1. Add SUPABASE_URL and SUPABASE_ANON_KEY to your app's environment");
265
270
  console.log(" 2. Wrap your app with <AutoshipProvider>");
@@ -300,11 +305,11 @@ async function runMigration(databaseUrl, migrationSql) {
300
305
  let allTablesExist = true;
301
306
  for (const table of tables) {
302
307
  try {
303
- await sql.unsafe(`SELECT 1 FROM ${table} LIMIT 0`);
304
- console.log(` [x] ${table}`);
308
+ await sql.unsafe(`SELECT 1 FROM autoship.${table} LIMIT 0`);
309
+ console.log(` [x] autoship.${table}`);
305
310
  }
306
311
  catch {
307
- console.log(` [ ] ${table} - NOT FOUND`);
312
+ console.log(` [ ] autoship.${table} - NOT FOUND`);
308
313
  allTablesExist = false;
309
314
  }
310
315
  }
@@ -1,7 +1,7 @@
1
1
  import { useCallback, useEffect, useState } from "react";
2
2
  import { useAutoshipContext } from "../AutoshipProvider";
3
3
  export function useTasks() {
4
- const { supabase, userId } = useAutoshipContext();
4
+ const { supabase, userId, schema } = useAutoshipContext();
5
5
  const [tasks, setTasks] = useState([]);
6
6
  const [loading, setLoading] = useState(true);
7
7
  const loadTasks = useCallback(async () => {
@@ -42,7 +42,7 @@ export function useTasks() {
42
42
  .channel("agent_tasks_changes")
43
43
  .on("postgres_changes", {
44
44
  event: "*",
45
- schema: "public",
45
+ schema: schema,
46
46
  table: "agent_tasks",
47
47
  filter: userId ? `submitted_by=eq.${userId}` : undefined,
48
48
  }, () => {
@@ -52,6 +52,6 @@ export function useTasks() {
52
52
  return () => {
53
53
  channel.unsubscribe();
54
54
  };
55
- }, [supabase, userId, loadTasks]);
55
+ }, [supabase, userId, schema, loadTasks]);
56
56
  return { tasks, loading, refresh: loadTasks };
57
57
  }
@@ -1,10 +1,32 @@
1
1
  -- Autoship MCP Initial Schema
2
2
  -- Tables: agent_tasks, task_categories, task_category_assignments, task_questions
3
3
 
4
+ -- =============================================================================
5
+ -- Create autoship schema to isolate from other schemas
6
+ -- =============================================================================
7
+ CREATE SCHEMA IF NOT EXISTS autoship;
8
+
9
+ -- Set search_path for this session to use autoship schema
10
+ SET search_path TO autoship, public;
11
+
12
+ -- =============================================================================
13
+ -- Expose the autoship schema via PostgREST API
14
+ -- Grant usage on the schema to the API roles
15
+ -- =============================================================================
16
+ GRANT USAGE ON SCHEMA autoship TO anon, authenticated, service_role;
17
+
18
+ -- Grant table permissions to service_role (full access)
19
+ ALTER DEFAULT PRIVILEGES IN SCHEMA autoship GRANT ALL ON TABLES TO service_role;
20
+ ALTER DEFAULT PRIVILEGES IN SCHEMA autoship GRANT ALL ON SEQUENCES TO service_role;
21
+
22
+ -- Grant table permissions to anon and authenticated (controlled by RLS)
23
+ ALTER DEFAULT PRIVILEGES IN SCHEMA autoship GRANT SELECT, INSERT, UPDATE, DELETE ON TABLES TO anon, authenticated;
24
+ ALTER DEFAULT PRIVILEGES IN SCHEMA autoship GRANT USAGE ON SEQUENCES TO anon, authenticated;
25
+
4
26
  -- =============================================================================
5
27
  -- Categories table (for tagging tasks)
6
28
  -- =============================================================================
7
- CREATE TABLE IF NOT EXISTS task_categories (
29
+ CREATE TABLE IF NOT EXISTS autoship.task_categories (
8
30
  id TEXT PRIMARY KEY,
9
31
  name TEXT NOT NULL UNIQUE,
10
32
  description TEXT,
@@ -15,7 +37,7 @@ CREATE TABLE IF NOT EXISTS task_categories (
15
37
  -- =============================================================================
16
38
  -- Agent tasks table (main tasks table)
17
39
  -- =============================================================================
18
- CREATE TABLE IF NOT EXISTS agent_tasks (
40
+ CREATE TABLE IF NOT EXISTS autoship.agent_tasks (
19
41
  id TEXT PRIMARY KEY,
20
42
  title TEXT NOT NULL,
21
43
  description TEXT NOT NULL,
@@ -33,29 +55,29 @@ CREATE TABLE IF NOT EXISTS agent_tasks (
33
55
  );
34
56
 
35
57
  -- Index for finding pending tasks quickly
36
- CREATE INDEX idx_agent_tasks_status_priority ON agent_tasks(status, priority DESC);
58
+ CREATE INDEX idx_agent_tasks_status_priority ON autoship.agent_tasks(status, priority DESC);
37
59
 
38
60
  -- Index for user's tasks (React components)
39
- CREATE INDEX idx_agent_tasks_submitted_by ON agent_tasks(submitted_by);
61
+ CREATE INDEX idx_agent_tasks_submitted_by ON autoship.agent_tasks(submitted_by);
40
62
 
41
63
  -- =============================================================================
42
64
  -- Category assignments (many-to-many relationship)
43
65
  -- =============================================================================
44
- CREATE TABLE IF NOT EXISTS task_category_assignments (
45
- task_id TEXT NOT NULL REFERENCES agent_tasks(id) ON DELETE CASCADE,
46
- category_id TEXT NOT NULL REFERENCES task_categories(id) ON DELETE CASCADE,
66
+ CREATE TABLE IF NOT EXISTS autoship.task_category_assignments (
67
+ task_id TEXT NOT NULL REFERENCES autoship.agent_tasks(id) ON DELETE CASCADE,
68
+ category_id TEXT NOT NULL REFERENCES autoship.task_categories(id) ON DELETE CASCADE,
47
69
  created_at TIMESTAMPTZ DEFAULT NOW(),
48
70
  PRIMARY KEY (task_id, category_id)
49
71
  );
50
72
 
51
- CREATE INDEX idx_task_category_assignments_category ON task_category_assignments(category_id);
73
+ CREATE INDEX idx_task_category_assignments_category ON autoship.task_category_assignments(category_id);
52
74
 
53
75
  -- =============================================================================
54
76
  -- Questions and answers for tasks
55
77
  -- =============================================================================
56
- CREATE TABLE IF NOT EXISTS task_questions (
78
+ CREATE TABLE IF NOT EXISTS autoship.task_questions (
57
79
  id TEXT PRIMARY KEY,
58
- task_id TEXT NOT NULL REFERENCES agent_tasks(id) ON DELETE CASCADE,
80
+ task_id TEXT NOT NULL REFERENCES autoship.agent_tasks(id) ON DELETE CASCADE,
59
81
  question TEXT NOT NULL,
60
82
  answer TEXT, -- NULL until answered
61
83
  asked_by TEXT DEFAULT 'agent', -- 'agent' or 'user'
@@ -63,13 +85,13 @@ CREATE TABLE IF NOT EXISTS task_questions (
63
85
  answered_at TIMESTAMPTZ
64
86
  );
65
87
 
66
- CREATE INDEX idx_task_questions_task ON task_questions(task_id);
67
- CREATE INDEX idx_task_questions_unanswered ON task_questions(task_id) WHERE answer IS NULL;
88
+ CREATE INDEX idx_task_questions_task ON autoship.task_questions(task_id);
89
+ CREATE INDEX idx_task_questions_unanswered ON autoship.task_questions(task_id) WHERE answer IS NULL;
68
90
 
69
91
  -- =============================================================================
70
92
  -- Trigger to update updated_at on agent_tasks
71
93
  -- =============================================================================
72
- CREATE OR REPLACE FUNCTION update_agent_tasks_updated_at()
94
+ CREATE OR REPLACE FUNCTION autoship.update_agent_tasks_updated_at()
73
95
  RETURNS TRIGGER AS $$
74
96
  BEGIN
75
97
  NEW.updated_at = NOW();
@@ -78,32 +100,32 @@ END;
78
100
  $$ LANGUAGE plpgsql;
79
101
 
80
102
  CREATE TRIGGER agent_tasks_updated_at
81
- BEFORE UPDATE ON agent_tasks
103
+ BEFORE UPDATE ON autoship.agent_tasks
82
104
  FOR EACH ROW
83
- EXECUTE FUNCTION update_agent_tasks_updated_at();
105
+ EXECUTE FUNCTION autoship.update_agent_tasks_updated_at();
84
106
 
85
107
  -- =============================================================================
86
108
  -- Row Level Security
87
109
  -- =============================================================================
88
110
 
89
111
  -- Enable RLS on all tables
90
- ALTER TABLE agent_tasks ENABLE ROW LEVEL SECURITY;
91
- ALTER TABLE task_categories ENABLE ROW LEVEL SECURITY;
92
- ALTER TABLE task_category_assignments ENABLE ROW LEVEL SECURITY;
93
- ALTER TABLE task_questions ENABLE ROW LEVEL SECURITY;
112
+ ALTER TABLE autoship.agent_tasks ENABLE ROW LEVEL SECURITY;
113
+ ALTER TABLE autoship.task_categories ENABLE ROW LEVEL SECURITY;
114
+ ALTER TABLE autoship.task_category_assignments ENABLE ROW LEVEL SECURITY;
115
+ ALTER TABLE autoship.task_questions ENABLE ROW LEVEL SECURITY;
94
116
 
95
117
  -- Service role has full access (used by the MCP server)
96
118
  CREATE POLICY "Service role has full access to agent_tasks"
97
- ON agent_tasks FOR ALL USING (true) WITH CHECK (true);
119
+ ON autoship.agent_tasks FOR ALL USING (true) WITH CHECK (true);
98
120
 
99
121
  CREATE POLICY "Service role has full access to task_categories"
100
- ON task_categories FOR ALL USING (true) WITH CHECK (true);
122
+ ON autoship.task_categories FOR ALL USING (true) WITH CHECK (true);
101
123
 
102
124
  CREATE POLICY "Service role has full access to task_category_assignments"
103
- ON task_category_assignments FOR ALL USING (true) WITH CHECK (true);
125
+ ON autoship.task_category_assignments FOR ALL USING (true) WITH CHECK (true);
104
126
 
105
127
  CREATE POLICY "Service role has full access to task_questions"
106
- ON task_questions FOR ALL USING (true) WITH CHECK (true);
128
+ ON autoship.task_questions FOR ALL USING (true) WITH CHECK (true);
107
129
 
108
130
  -- =============================================================================
109
131
  -- Policies for React components (using anon key)
@@ -111,33 +133,47 @@ CREATE POLICY "Service role has full access to task_questions"
111
133
 
112
134
  -- Users can view their own tasks or tasks without a submitter
113
135
  CREATE POLICY "Users can view their own tasks"
114
- ON agent_tasks FOR SELECT
136
+ ON autoship.agent_tasks FOR SELECT
115
137
  USING (submitted_by IS NULL OR submitted_by = coalesce(auth.uid()::text, submitted_by));
116
138
 
117
139
  -- Anyone can insert tasks
118
140
  CREATE POLICY "Anyone can insert tasks"
119
- ON agent_tasks FOR INSERT
141
+ ON autoship.agent_tasks FOR INSERT
120
142
  WITH CHECK (true);
121
143
 
122
144
  -- Users can update their own tasks (for answering questions)
123
145
  CREATE POLICY "Users can update their own tasks"
124
- ON agent_tasks FOR UPDATE
146
+ ON autoship.agent_tasks FOR UPDATE
125
147
  USING (submitted_by IS NULL OR submitted_by = coalesce(auth.uid()::text, submitted_by));
126
148
 
127
149
  -- Users can view questions for their tasks
128
150
  CREATE POLICY "Users can view questions for their tasks"
129
- ON task_questions FOR SELECT
151
+ ON autoship.task_questions FOR SELECT
130
152
  USING (EXISTS (
131
- SELECT 1 FROM agent_tasks
132
- WHERE agent_tasks.id = task_questions.task_id
133
- AND (agent_tasks.submitted_by IS NULL OR agent_tasks.submitted_by = coalesce(auth.uid()::text, agent_tasks.submitted_by))
153
+ SELECT 1 FROM autoship.agent_tasks
154
+ WHERE autoship.agent_tasks.id = autoship.task_questions.task_id
155
+ AND (autoship.agent_tasks.submitted_by IS NULL OR autoship.agent_tasks.submitted_by = coalesce(auth.uid()::text, autoship.agent_tasks.submitted_by))
134
156
  ));
135
157
 
136
158
  -- Users can update questions (to provide answers)
137
159
  CREATE POLICY "Users can update questions for their tasks"
138
- ON task_questions FOR UPDATE
160
+ ON autoship.task_questions FOR UPDATE
139
161
  USING (EXISTS (
140
- SELECT 1 FROM agent_tasks
141
- WHERE agent_tasks.id = task_questions.task_id
142
- AND (agent_tasks.submitted_by IS NULL OR agent_tasks.submitted_by = coalesce(auth.uid()::text, agent_tasks.submitted_by))
162
+ SELECT 1 FROM autoship.agent_tasks
163
+ WHERE autoship.agent_tasks.id = autoship.task_questions.task_id
164
+ AND (autoship.agent_tasks.submitted_by IS NULL OR autoship.agent_tasks.submitted_by = coalesce(auth.uid()::text, autoship.agent_tasks.submitted_by))
143
165
  ));
166
+
167
+ -- =============================================================================
168
+ -- Grant explicit permissions on tables (since ALTER DEFAULT PRIVILEGES only
169
+ -- affects future tables, not tables created in the same transaction)
170
+ -- =============================================================================
171
+ GRANT ALL ON autoship.agent_tasks TO service_role;
172
+ GRANT ALL ON autoship.task_categories TO service_role;
173
+ GRANT ALL ON autoship.task_category_assignments TO service_role;
174
+ GRANT ALL ON autoship.task_questions TO service_role;
175
+
176
+ GRANT SELECT, INSERT, UPDATE, DELETE ON autoship.agent_tasks TO anon, authenticated;
177
+ GRANT SELECT, INSERT, UPDATE, DELETE ON autoship.task_categories TO anon, authenticated;
178
+ GRANT SELECT, INSERT, UPDATE, DELETE ON autoship.task_category_assignments TO anon, authenticated;
179
+ GRANT SELECT, INSERT, UPDATE, DELETE ON autoship.task_questions TO anon, authenticated;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@autoship/react",
3
- "version": "0.3.0",
3
+ "version": "0.5.0",
4
4
  "type": "module",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -17,7 +17,7 @@
17
17
  "dist"
18
18
  ],
19
19
  "scripts": {
20
- "build": "tsc && cp ../../README.md dist/ && npm run copy-migrations",
20
+ "build": "tsc && cp ../../README.md README.md && npm run copy-migrations",
21
21
  "copy-migrations": "mkdir -p dist/migrations && cp ../../supabase/migrations/*.sql dist/migrations/",
22
22
  "dev": "tsc --watch",
23
23
  "cli": "node dist/cli/autoship.js"