Initial implementation of TriggerShell

A Python CLI (typer) that bootstraps Node/pnpm and launches a Next.js 16 web
app for running configured shell scripts: YAML config validated by a shared
Zod schema, dynamic per-script forms mapped to shadcn controls, argv-safe
execa execution with live WebSocket streaming, SQLite/Drizzle run history,
and optional argon2 session + API token auth.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
2026-08-15 18:37:30 +02:00
co-authored by Claude Sonnet 5
commit ced99a8e75
117 changed files with 17367 additions and 0 deletions
+38
View File
@@ -0,0 +1,38 @@
CREATE TABLE `api_tokens` (
`id` text PRIMARY KEY NOT NULL,
`name` text NOT NULL,
`token_hash` text NOT NULL,
`created_at` integer NOT NULL,
`last_used_at` integer
);
--> statement-breakpoint
CREATE UNIQUE INDEX `api_tokens_name_unique` ON `api_tokens` (`name`);--> statement-breakpoint
CREATE TABLE `runs` (
`id` text PRIMARY KEY NOT NULL,
`script_id` text NOT NULL,
`script_name` text NOT NULL,
`status` text DEFAULT 'queued' NOT NULL,
`variables` text NOT NULL,
`resolved_command` text NOT NULL,
`pid` integer,
`exit_code` integer,
`started_at` integer,
`ended_at` integer,
`timeout_seconds` integer,
`triggered_by` text NOT NULL,
`log_file_path` text NOT NULL,
`error_message` text,
`created_at` integer NOT NULL
);
--> statement-breakpoint
CREATE INDEX `runs_script_id_idx` ON `runs` (`script_id`);--> statement-breakpoint
CREATE INDEX `runs_status_idx` ON `runs` (`status`);--> statement-breakpoint
CREATE TABLE `users` (
`id` text PRIMARY KEY NOT NULL,
`username` text NOT NULL,
`password_hash` text NOT NULL,
`created_at` integer NOT NULL,
`last_login_at` integer
);
--> statement-breakpoint
CREATE UNIQUE INDEX `users_username_unique` ON `users` (`username`);
+247
View File
@@ -0,0 +1,247 @@
{
"version": "6",
"dialect": "sqlite",
"id": "293a5752-68a4-4e8a-89a6-fadaebd14e3b",
"prevId": "00000000-0000-0000-0000-000000000000",
"tables": {
"api_tokens": {
"name": "api_tokens",
"columns": {
"id": {
"name": "id",
"type": "text",
"primaryKey": true,
"notNull": true,
"autoincrement": false
},
"name": {
"name": "name",
"type": "text",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"token_hash": {
"name": "token_hash",
"type": "text",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"created_at": {
"name": "created_at",
"type": "integer",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"last_used_at": {
"name": "last_used_at",
"type": "integer",
"primaryKey": false,
"notNull": false,
"autoincrement": false
}
},
"indexes": {
"api_tokens_name_unique": {
"name": "api_tokens_name_unique",
"columns": ["name"],
"isUnique": true
}
},
"foreignKeys": {},
"compositePrimaryKeys": {},
"uniqueConstraints": {},
"checkConstraints": {}
},
"runs": {
"name": "runs",
"columns": {
"id": {
"name": "id",
"type": "text",
"primaryKey": true,
"notNull": true,
"autoincrement": false
},
"script_id": {
"name": "script_id",
"type": "text",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"script_name": {
"name": "script_name",
"type": "text",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"status": {
"name": "status",
"type": "text",
"primaryKey": false,
"notNull": true,
"autoincrement": false,
"default": "'queued'"
},
"variables": {
"name": "variables",
"type": "text",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"resolved_command": {
"name": "resolved_command",
"type": "text",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"pid": {
"name": "pid",
"type": "integer",
"primaryKey": false,
"notNull": false,
"autoincrement": false
},
"exit_code": {
"name": "exit_code",
"type": "integer",
"primaryKey": false,
"notNull": false,
"autoincrement": false
},
"started_at": {
"name": "started_at",
"type": "integer",
"primaryKey": false,
"notNull": false,
"autoincrement": false
},
"ended_at": {
"name": "ended_at",
"type": "integer",
"primaryKey": false,
"notNull": false,
"autoincrement": false
},
"timeout_seconds": {
"name": "timeout_seconds",
"type": "integer",
"primaryKey": false,
"notNull": false,
"autoincrement": false
},
"triggered_by": {
"name": "triggered_by",
"type": "text",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"log_file_path": {
"name": "log_file_path",
"type": "text",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"error_message": {
"name": "error_message",
"type": "text",
"primaryKey": false,
"notNull": false,
"autoincrement": false
},
"created_at": {
"name": "created_at",
"type": "integer",
"primaryKey": false,
"notNull": true,
"autoincrement": false
}
},
"indexes": {
"runs_script_id_idx": {
"name": "runs_script_id_idx",
"columns": ["script_id"],
"isUnique": false
},
"runs_status_idx": {
"name": "runs_status_idx",
"columns": ["status"],
"isUnique": false
}
},
"foreignKeys": {},
"compositePrimaryKeys": {},
"uniqueConstraints": {},
"checkConstraints": {}
},
"users": {
"name": "users",
"columns": {
"id": {
"name": "id",
"type": "text",
"primaryKey": true,
"notNull": true,
"autoincrement": false
},
"username": {
"name": "username",
"type": "text",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"password_hash": {
"name": "password_hash",
"type": "text",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"created_at": {
"name": "created_at",
"type": "integer",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"last_login_at": {
"name": "last_login_at",
"type": "integer",
"primaryKey": false,
"notNull": false,
"autoincrement": false
}
},
"indexes": {
"users_username_unique": {
"name": "users_username_unique",
"columns": ["username"],
"isUnique": true
}
},
"foreignKeys": {},
"compositePrimaryKeys": {},
"uniqueConstraints": {},
"checkConstraints": {}
}
},
"views": {},
"enums": {},
"_meta": {
"schemas": {},
"tables": {},
"columns": {}
},
"internal": {
"indexes": {}
}
}
+13
View File
@@ -0,0 +1,13 @@
{
"version": "7",
"dialect": "sqlite",
"entries": [
{
"idx": 0,
"version": "6",
"when": 1786809343994,
"tag": "0000_thick_reaper",
"breakpoints": true
}
]
}