merge: reconcile published native prerequisite and current master

Preserve canonical startup ownership, scoped evidence, current Storybook IDs, and the Codex form controls while carrying Claude effort and immutable source bindings.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
This commit is contained in:
DottaandPaperclip committed 2026-10-12 20:40:11 -05:00
commit 48ffca9438
415 files changed
+22501 -15340

No files matched your search

@@ -5,7 +5,6 @@ import { afterEach, describe, expect, it, vi } from "vitest";
vi.mock("node:child_process", async (importOriginal) => {
const actual = await importOriginal<typeof import("node:child_process")>();
// Execute the authored remote command locally, through both subprocess paths.
return {
...actual,
execFile: vi.fn((file: string, args: string[], options: object, callback: Parameters<typeof actual.execFile>[3]) => {
-2
View File
@@ -68,8 +68,6 @@ export function createSshCommandManagedRuntimeRunner(input: {
const envPrefix = envEntries.length > 0
? `env ${envEntries.map(([key, value]) => shellQuote(`${key}=${value}`)).join(" ")} `
: "";
// Keep sh -c's command name and positional arguments intact. Flattening
// its script loses $0/$1/... and breaks native runner launch/identity.
const commandScript = `exec ${envPrefix}${[shellQuote(command), ...args.map((arg) => shellQuote(arg))].join(" ")}`;
const remoteCommand = `cd ${shellQuote(cwd)} && ${commandScript}`;
@@ -0,0 +1,39 @@
CREATE TABLE IF NOT EXISTS "chat_slack_manager_grants" (
"id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
"company_id" uuid NOT NULL,
"user_id" text NOT NULL,
"slack_user_id" text NOT NULL,
"workspace_id" text NOT NULL,
"workspace_name" text NOT NULL,
"manager_app_id" text NOT NULL,
"status" text DEFAULT 'active' NOT NULL,
"access_secret_id" uuid,
"refresh_secret_id" uuid,
"expires_at" timestamp with time zone,
"created_at" timestamp with time zone DEFAULT now() NOT NULL,
"updated_at" timestamp with time zone DEFAULT now() NOT NULL,
CONSTRAINT "chat_slack_manager_grants_status_check" CHECK ("chat_slack_manager_grants"."status" in ('active', 'revoked', 'reauthorize'))
);
--> statement-breakpoint
ALTER TABLE "chat_slack_registrations" ADD COLUMN IF NOT EXISTS "manager_grant_id" uuid;
--> statement-breakpoint
DO $$ BEGIN
ALTER TABLE "chat_slack_manager_grants" ADD CONSTRAINT "chat_slack_manager_grants_company_id_companies_id_fk" FOREIGN KEY ("company_id") REFERENCES "public"."companies"("id") ON DELETE cascade ON UPDATE no action;
EXCEPTION WHEN duplicate_object THEN NULL; END $$;
--> statement-breakpoint
CREATE UNIQUE INDEX IF NOT EXISTS "chat_slack_manager_grants_company_id_idx" ON "chat_slack_manager_grants" USING btree ("company_id","id");
--> statement-breakpoint
CREATE UNIQUE INDEX IF NOT EXISTS "chat_slack_manager_grants_owner_idx" ON "chat_slack_manager_grants" USING btree ("company_id","user_id","manager_app_id","workspace_id");
--> statement-breakpoint
DO $$ BEGIN
ALTER TABLE "chat_slack_registrations" ADD CONSTRAINT "chat_slack_registrations_company_id_manager_grant_id_chat_slack_manager_grants_company_id_id_fk" FOREIGN KEY ("company_id","manager_grant_id") REFERENCES "public"."chat_slack_manager_grants"("company_id","id") ON DELETE no action ON UPDATE no action;
EXCEPTION WHEN duplicate_object THEN NULL; END $$;
--> statement-breakpoint
ALTER TABLE "chat_slack_manager_grants" ADD COLUMN IF NOT EXISTS "revision" integer DEFAULT 0 NOT NULL;
--> statement-breakpoint
ALTER TABLE "chat_slack_manager_grants" ADD COLUMN IF NOT EXISTS "rate_limits" jsonb DEFAULT '{}'::jsonb NOT NULL;
@@ -1,6 +1,6 @@
{
"id": "0a93bc99-bf0c-4ea2-ab27-6043b6746cd5",
"prevId": "76861d12-d9a9-4f5f-bcbc-0fb06c0addbc",
"id": "18c156f2-8344-4282-98b7-f702f0035c81",
"prevId": "39d82f2c-8fd5-4606-84df-f51880dbd6a7",
"version": "7",
"dialect": "postgresql",
"tables": {
@@ -416,6 +416,12 @@
"primaryKey": false,
"notNull": false
},
"fast_response_request_id": {
"name": "fast_response_request_id",
"type": "uuid",
"primaryKey": false,
"notNull": false
},
"agent_id": {
"name": "agent_id",
"type": "uuid",
@@ -462,6 +468,27 @@
}
},
"indexes": {
"budget_reservations_fast_response_idx": {
"name": "budget_reservations_fast_response_idx",
"columns": [
{
"expression": "company_id",
"isExpression": false,
"asc": true,
"nulls": "last"
},
{
"expression": "fast_response_request_id",
"isExpression": false,
"asc": true,
"nulls": "last"
}
],
"isUnique": true,
"concurrently": false,
"method": "btree",
"with": {}
},
"budget_reservations_decision_idx": {
"name": "budget_reservations_decision_idx",
"columns": [
@@ -580,7 +607,7 @@
"checkConstraints": {
"budget_reservations_source_check": {
"name": "budget_reservations_source_check",
"value": "(\"budget_reservations\".\"run_id\" is not null)::int + (\"budget_reservations\".\"decision_invocation_id\" is not null)::int = 1"
"value": "(\"budget_reservations\".\"run_id\" is not null)::int + (\"budget_reservations\".\"decision_invocation_id\" is not null)::int + (\"budget_reservations\".\"fast_response_request_id\" is not null)::int = 1"
},
"budget_reservations_state_check": {
"name": "budget_reservations_state_check",
@@ -3737,6 +3764,28 @@
"method": "btree",
"with": {}
},
"agent_wakeup_requests_question_response_history_idx": {
"name": "agent_wakeup_requests_question_response_history_idx",
"columns": [
{
"expression": "company_id",
"isExpression": false,
"asc": true,
"nulls": "last"
},
{
"expression": "idempotency_key",
"isExpression": false,
"asc": true,
"nulls": "last"
}
],
"isUnique": false,
"where": "\"agent_wakeup_requests\".\"idempotency_key\" LIKE 'question-response:%'",
"concurrently": true,
"method": "btree",
"with": {}
},
"agent_wakeup_requests_connection_intent_delivery_idempotency_uq": {
"name": "agent_wakeup_requests_connection_intent_delivery_idempotency_uq",
"columns": [
@@ -12384,6 +12433,189 @@
},
"isRLSEnabled": false
},
"public.chat_slack_manager_grants": {
"name": "chat_slack_manager_grants",
"schema": "",
"columns": {
"id": {
"name": "id",
"type": "uuid",
"primaryKey": true,
"notNull": true,
"default": "gen_random_uuid()"
},
"company_id": {
"name": "company_id",
"type": "uuid",
"primaryKey": false,
"notNull": true
},
"user_id": {
"name": "user_id",
"type": "text",
"primaryKey": false,
"notNull": true
},
"slack_user_id": {
"name": "slack_user_id",
"type": "text",
"primaryKey": false,
"notNull": true
},
"workspace_id": {
"name": "workspace_id",
"type": "text",
"primaryKey": false,
"notNull": true
},
"workspace_name": {
"name": "workspace_name",
"type": "text",
"primaryKey": false,
"notNull": true
},
"manager_app_id": {
"name": "manager_app_id",
"type": "text",
"primaryKey": false,
"notNull": true
},
"status": {
"name": "status",
"type": "text",
"primaryKey": false,
"notNull": true,
"default": "'active'"
},
"access_secret_id": {
"name": "access_secret_id",
"type": "uuid",
"primaryKey": false,
"notNull": false
},
"refresh_secret_id": {
"name": "refresh_secret_id",
"type": "uuid",
"primaryKey": false,
"notNull": false
},
"revision": {
"name": "revision",
"type": "integer",
"primaryKey": false,
"notNull": true,
"default": 0
},
"rate_limits": {
"name": "rate_limits",
"type": "jsonb",
"primaryKey": false,
"notNull": true,
"default": "'{}'::jsonb"
},
"expires_at": {
"name": "expires_at",
"type": "timestamp with time zone",
"primaryKey": false,
"notNull": false
},
"created_at": {
"name": "created_at",
"type": "timestamp with time zone",
"primaryKey": false,
"notNull": true,
"default": "now()"
},
"updated_at": {
"name": "updated_at",
"type": "timestamp with time zone",
"primaryKey": false,
"notNull": true,
"default": "now()"
}
},
"indexes": {
"chat_slack_manager_grants_company_id_idx": {
"name": "chat_slack_manager_grants_company_id_idx",
"columns": [
{
"expression": "company_id",
"isExpression": false,
"asc": true,
"nulls": "last"
},
{
"expression": "id",
"isExpression": false,
"asc": true,
"nulls": "last"
}
],
"isUnique": true,
"concurrently": false,
"method": "btree",
"with": {}
},
"chat_slack_manager_grants_owner_idx": {
"name": "chat_slack_manager_grants_owner_idx",
"columns": [
{
"expression": "company_id",
"isExpression": false,
"asc": true,
"nulls": "last"
},
{
"expression": "user_id",
"isExpression": false,
"asc": true,
"nulls": "last"
},
{
"expression": "manager_app_id",
"isExpression": false,
"asc": true,
"nulls": "last"
},
{
"expression": "workspace_id",
"isExpression": false,
"asc": true,
"nulls": "last"
}
],
"isUnique": true,
"concurrently": false,
"method": "btree",
"with": {}
}
},
"foreignKeys": {
"chat_slack_manager_grants_company_id_companies_id_fk": {
"name": "chat_slack_manager_grants_company_id_companies_id_fk",
"tableFrom": "chat_slack_manager_grants",
"tableTo": "companies",
"columnsFrom": [
"company_id"
],
"columnsTo": [
"id"
],
"onDelete": "cascade",
"onUpdate": "no action"
}
},
"compositePrimaryKeys": {},
"uniqueConstraints": {},
"policies": {},
"checkConstraints": {
"chat_slack_manager_grants_status_check": {
"name": "chat_slack_manager_grants_status_check",
"value": "\"chat_slack_manager_grants\".\"status\" in ('active', 'revoked', 'reauthorize')"
}
},
"isRLSEnabled": false
},
"public.chat_slack_registrations": {
"name": "chat_slack_registrations",
"schema": "",
@@ -12400,6 +12632,12 @@
"primaryKey": false,
"notNull": true
},
"manager_grant_id": {
"name": "manager_grant_id",
"type": "uuid",
"primaryKey": false,
"notNull": false
},
"request_id": {
"name": "request_id",
"type": "uuid",
@@ -12490,6 +12728,21 @@
},
"indexes": {},
"foreignKeys": {
"chat_slack_registrations_company_id_manager_grant_id_chat_slack_manager_grants_company_id_id_fk": {
"name": "chat_slack_registrations_company_id_manager_grant_id_chat_slack_manager_grants_company_id_id_fk",
"tableFrom": "chat_slack_registrations",
"tableTo": "chat_slack_manager_grants",
"columnsFrom": [
"company_id",
"manager_grant_id"
],
"columnsTo": [
"company_id",
"id"
],
"onDelete": "no action",
"onUpdate": "no action"
},
"chat_slack_registrations_company_id_endpoint_id_chat_endpoints_company_id_id_fk": {
"name": "chat_slack_registrations_company_id_endpoint_id_chat_endpoints_company_id_id_fk",
"tableFrom": "chat_slack_registrations",
@@ -16725,6 +16978,19 @@
"primaryKey": false,
"notNull": false
},
"package_mode": {
"name": "package_mode",
"type": "text",
"primaryKey": false,
"notNull": true,
"default": "'skills'"
},
"repository_package": {
"name": "repository_package",
"type": "jsonb",
"primaryKey": false,
"notNull": false
},
"excluded_folders": {
"name": "excluded_folders",
"type": "jsonb",
@@ -17052,6 +17318,87 @@
"checkConstraints": {},
"isRLSEnabled": false
},
"public.company_skill_repository_snapshots": {
"name": "company_skill_repository_snapshots",
"schema": "",
"columns": {
"id": {
"name": "id",
"type": "uuid",
"primaryKey": true,
"notNull": true,
"default": "gen_random_uuid()"
},
"company_id": {
"name": "company_id",
"type": "uuid",
"primaryKey": false,
"notNull": true
},
"content_hash": {
"name": "content_hash",
"type": "text",
"primaryKey": false,
"notNull": true
},
"file_inventory": {
"name": "file_inventory",
"type": "jsonb",
"primaryKey": false,
"notNull": true
},
"created_at": {
"name": "created_at",
"type": "timestamp with time zone",
"primaryKey": false,
"notNull": true,
"default": "now()"
}
},
"indexes": {
"company_skill_repository_snapshots_content_idx": {
"name": "company_skill_repository_snapshots_content_idx",
"columns": [
{
"expression": "company_id",
"isExpression": false,
"asc": true,
"nulls": "last"
},
{
"expression": "content_hash",
"isExpression": false,
"asc": true,
"nulls": "last"
}
],
"isUnique": true,
"concurrently": false,
"method": "btree",
"with": {}
}
},
"foreignKeys": {
"company_skill_repository_snapshots_company_id_companies_id_fk": {
"name": "company_skill_repository_snapshots_company_id_companies_id_fk",
"tableFrom": "company_skill_repository_snapshots",
"tableTo": "companies",
"columnsFrom": [
"company_id"
],
"columnsTo": [
"id"
],
"onDelete": "cascade",
"onUpdate": "no action"
}
},
"compositePrimaryKeys": {},
"uniqueConstraints": {},
"policies": {},
"checkConstraints": {},
"isRLSEnabled": false
},
"public.company_skill_stars": {
"name": "company_skill_stars",
"schema": "",
@@ -17906,6 +18253,18 @@
"primaryKey": false,
"notNull": true
},
"repository_snapshot_id": {
"name": "repository_snapshot_id",
"type": "uuid",
"primaryKey": false,
"notNull": false
},
"repository_skill_path": {
"name": "repository_skill_path",
"type": "text",
"primaryKey": false,
"notNull": false
},
"revision_number": {
"name": "revision_number",
"type": "integer",
@@ -18062,6 +18421,19 @@
"onDelete": "cascade",
"onUpdate": "no action"
},
"company_skill_versions_repository_snapshot_id_company_skill_repository_snapshots_id_fk": {
"name": "company_skill_versions_repository_snapshot_id_company_skill_repository_snapshots_id_fk",
"tableFrom": "company_skill_versions",
"tableTo": "company_skill_repository_snapshots",
"columnsFrom": [
"repository_snapshot_id"
],
"columnsTo": [
"id"
],
"onDelete": "restrict",
"onUpdate": "no action"
},
"company_skill_versions_author_agent_id_agents_id_fk": {
"name": "company_skill_versions_author_agent_id_agents_id_fk",
"tableFrom": "company_skill_versions",
@@ -19576,6 +19948,34 @@
"method": "btree",
"with": {}
},
"cost_events_data_quality_idx": {
"name": "cost_events_data_quality_idx",
"columns": [
{
"expression": "company_id",
"isExpression": false,
"asc": true,
"nulls": "last"
},
{
"expression": "occurred_at",
"isExpression": false,
"asc": false,
"nulls": "last"
},
{
"expression": "id",
"isExpression": false,
"asc": true,
"nulls": "last"
}
],
"isUnique": false,
"where": "\"cost_events\".\"billing_type\" = 'unknown' or (\"cost_events\".\"cost_status\" = 'unpriced' and \"cost_events\".\"billing_type\" <> 'subscription_included')",
"concurrently": false,
"method": "btree",
"with": {}
},
"cost_events_company_occurred_idx": {
"name": "cost_events_company_occurred_idx",
"columns": [
@@ -19826,7 +20226,7 @@
"checkConstraints": {
"cost_events_usage_kind_check": {
"name": "cost_events_usage_kind_check",
"value": "\"cost_events\".\"usage_kind\" = 'decision' or (\"cost_events\".\"usage_kind\" = 'agent' and \"cost_events\".\"agent_id\" is not null)"
"value": "\"cost_events\".\"usage_kind\" in ('decision', 'fast_response') or (\"cost_events\".\"usage_kind\" = 'agent' and \"cost_events\".\"agent_id\" is not null)"
},
"cost_events_nonnegative_amounts": {
"name": "cost_events_nonnegative_amounts",
@@ -27491,6 +27891,378 @@
"checkConstraints": {},
"isRLSEnabled": false
},
"public.company_fast_responses": {
"name": "company_fast_responses",
"schema": "",
"columns": {
"company_id": {
"name": "company_id",
"type": "uuid",
"primaryKey": true,
"notNull": true
},
"connection_id": {
"name": "connection_id",
"type": "uuid",
"primaryKey": false,
"notNull": false
},
"grant_id": {
"name": "grant_id",
"type": "uuid",
"primaryKey": false,
"notNull": false
},
"model": {
"name": "model",
"type": "text",
"primaryKey": false,
"notNull": false
},
"provider": {
"name": "provider",
"type": "text",
"primaryKey": false,
"notNull": false
},
"enabled": {
"name": "enabled",
"type": "boolean",
"primaryKey": false,
"notNull": true,
"default": false
},
"allow_sponsored": {
"name": "allow_sponsored",
"type": "boolean",
"primaryKey": false,
"notNull": true,
"default": true
},
"updated_at": {
"name": "updated_at",
"type": "timestamp with time zone",
"primaryKey": false,
"notNull": true,
"default": "now()"
}
},
"indexes": {},
"foreignKeys": {
"company_fast_responses_company_id_companies_id_fk": {
"name": "company_fast_responses_company_id_companies_id_fk",
"tableFrom": "company_fast_responses",
"tableTo": "companies",
"columnsFrom": [
"company_id"
],
"columnsTo": [
"id"
],
"onDelete": "cascade",
"onUpdate": "no action"
}
},
"compositePrimaryKeys": {},
"uniqueConstraints": {},
"policies": {},
"checkConstraints": {
"company_fast_responses_configured": {
"name": "company_fast_responses_configured",
"value": "(\"company_fast_responses\".\"connection_id\" is null) = (\"company_fast_responses\".\"grant_id\" is null) and (not \"company_fast_responses\".\"enabled\" or (\"company_fast_responses\".\"connection_id\" is not null and \"company_fast_responses\".\"model\" is not null))"
}
},
"isRLSEnabled": false
},
"public.fast_response_requests": {
"name": "fast_response_requests",
"schema": "",
"columns": {
"id": {
"name": "id",
"type": "uuid",
"primaryKey": true,
"notNull": true,
"default": "gen_random_uuid()"
},
"company_id": {
"name": "company_id",
"type": "uuid",
"primaryKey": false,
"notNull": true
},
"source_key": {
"name": "source_key",
"type": "text",
"primaryKey": false,
"notNull": true
},
"source_comment_id": {
"name": "source_comment_id",
"type": "uuid",
"primaryKey": false,
"notNull": false
},
"issue_id": {
"name": "issue_id",
"type": "uuid",
"primaryKey": false,
"notNull": false
},
"project_id": {
"name": "project_id",
"type": "uuid",
"primaryKey": false,
"notNull": false
},
"agent_id": {
"name": "agent_id",
"type": "uuid",
"primaryKey": false,
"notNull": false
},
"responsible_user_id": {
"name": "responsible_user_id",
"type": "text",
"primaryKey": false,
"notNull": false
},
"sponsored": {
"name": "sponsored",
"type": "boolean",
"primaryKey": false,
"notNull": true,
"default": false
},
"endpoint_id": {
"name": "endpoint_id",
"type": "uuid",
"primaryKey": false,
"notNull": false
},
"conversation_id": {
"name": "conversation_id",
"type": "uuid",
"primaryKey": false,
"notNull": false
},
"delivery_id": {
"name": "delivery_id",
"type": "uuid",
"primaryKey": false,
"notNull": false
},
"session_generation": {
"name": "session_generation",
"type": "integer",
"primaryKey": false,
"notNull": false
},
"status": {
"name": "status",
"type": "text",
"primaryKey": false,
"notNull": true,
"default": "'pending'"
},
"publication_status": {
"name": "publication_status",
"type": "text",
"primaryKey": false,
"notNull": true,
"default": "'pending'"
},
"connection_id": {
"name": "connection_id",
"type": "uuid",
"primaryKey": false,
"notNull": false
},
"grant_id": {
"name": "grant_id",
"type": "uuid",
"primaryKey": false,
"notNull": false
},
"provider": {
"name": "provider",
"type": "text",
"primaryKey": false,
"notNull": false
},
"model": {
"name": "model",
"type": "text",
"primaryKey": false,
"notNull": false
},
"provider_request_id": {
"name": "provider_request_id",
"type": "text",
"primaryKey": false,
"notNull": false
},
"cost_event_id": {
"name": "cost_event_id",
"type": "uuid",
"primaryKey": false,
"notNull": false
},
"error_code": {
"name": "error_code",
"type": "text",
"primaryKey": false,
"notNull": false
},
"comment_id": {
"name": "comment_id",
"type": "uuid",
"primaryKey": false,
"notNull": false
},
"accepted_at": {
"name": "accepted_at",
"type": "timestamp with time zone",
"primaryKey": false,
"notNull": true,
"default": "now()"
},
"expires_at": {
"name": "expires_at",
"type": "timestamp with time zone",
"primaryKey": false,
"notNull": true
},
"started_at": {
"name": "started_at",
"type": "timestamp with time zone",
"primaryKey": false,
"notNull": false
},
"finished_at": {
"name": "finished_at",
"type": "timestamp with time zone",
"primaryKey": false,
"notNull": false
},
"duration_ms": {
"name": "duration_ms",
"type": "integer",
"primaryKey": false,
"notNull": false
},
"input_tokens": {
"name": "input_tokens",
"type": "integer",
"primaryKey": false,
"notNull": false
},
"output_tokens": {
"name": "output_tokens",
"type": "integer",
"primaryKey": false,
"notNull": false
}
},
"indexes": {
"fast_response_requests_source_idx": {
"name": "fast_response_requests_source_idx",
"columns": [
{
"expression": "company_id",
"isExpression": false,
"asc": true,
"nulls": "last"
},
{
"expression": "source_key",
"isExpression": false,
"asc": true,
"nulls": "last"
}
],
"isUnique": true,
"concurrently": false,
"method": "btree",
"with": {}
},
"fast_response_requests_history_idx": {
"name": "fast_response_requests_history_idx",
"columns": [
{
"expression": "company_id",
"isExpression": false,
"asc": true,
"nulls": "last"
},
{
"expression": "accepted_at",
"isExpression": false,
"asc": true,
"nulls": "last"
}
],
"isUnique": false,
"concurrently": false,
"method": "btree",
"with": {}
},
"fast_response_requests_work_idx": {
"name": "fast_response_requests_work_idx",
"columns": [
{
"expression": "expires_at",
"isExpression": false,
"asc": true,
"nulls": "last"
}
],
"isUnique": false,
"where": "\"fast_response_requests\".\"status\" in ('pending', 'running')",
"concurrently": false,
"method": "btree",
"with": {}
}
},
"foreignKeys": {
"fast_response_requests_company_id_companies_id_fk": {
"name": "fast_response_requests_company_id_companies_id_fk",
"tableFrom": "fast_response_requests",
"tableTo": "companies",
"columnsFrom": [
"company_id"
],
"columnsTo": [
"id"
],
"onDelete": "cascade",
"onUpdate": "no action"
},
"fast_response_requests_cost_event_id_cost_events_id_fk": {
"name": "fast_response_requests_cost_event_id_cost_events_id_fk",
"tableFrom": "fast_response_requests",
"tableTo": "cost_events",
"columnsFrom": [
"cost_event_id"
],
"columnsTo": [
"id"
],
"onDelete": "no action",
"onUpdate": "no action"
}
},
"compositePrimaryKeys": {},
"uniqueConstraints": {},
"policies": {},
"checkConstraints": {
"fast_response_requests_status_check": {
"name": "fast_response_requests_status_check",
"value": "\"fast_response_requests\".\"status\" in ('pending', 'running', 'succeeded', 'failed', 'unknown', 'skipped')"
}
},
"isRLSEnabled": false
},
"public.feedback_exports": {
"name": "feedback_exports",
"schema": "",
@@ -29938,6 +30710,34 @@
"method": "btree",
"with": {}
},
"heartbeat_runs_cost_data_quality_idx": {
"name": "heartbeat_runs_cost_data_quality_idx",
"columns": [
{
"expression": "company_id",
"isExpression": false,
"asc": true,
"nulls": "last"
},
{
"expression": "coalesce(\"finished_at\", \"created_at\") desc",
"asc": true,
"isExpression": true,
"nulls": "last"
},
{
"expression": "id",
"isExpression": false,
"asc": true,
"nulls": "last"
}
],
"isUnique": false,
"where": "\"heartbeat_runs\".\"cost_accounting_pending\" = true and \"heartbeat_runs\".\"status\" in ('succeeded','failed','timed_out','cancelled','interrupted')",
"concurrently": false,
"method": "btree",
"with": {}
},
"heartbeat_runs_execution_status_delivery_idx": {
"name": "heartbeat_runs_execution_status_delivery_idx",
"columns": [
@@ -32392,6 +33192,19 @@
"primaryKey": false,
"notNull": false
},
"origin": {
"name": "origin",
"type": "text",
"primaryKey": false,
"notNull": true,
"default": "'comment'"
},
"fast_response_request_id": {
"name": "fast_response_request_id",
"type": "uuid",
"primaryKey": false,
"notNull": false
},
"body": {
"name": "body",
"type": "text",
+7
View File
@@ -2332,6 +2332,13 @@
"when": 1791807836288,
"tag": "0334_rare_slipstream",
"breakpoints": true
},
{
"idx": 335,
"version": "7",
"when": 1791832982875,
"tag": "0335_absurd_bulldozer",
"breakpoints": true
}
]
}
@@ -0,0 +1,26 @@
import { sql } from "drizzle-orm";
import { check, integer, jsonb, pgTable, text, timestamp, uniqueIndex, uuid } from "drizzle-orm/pg-core";
import { companies } from "./companies.js";
/** Reusable personal management authorization; never a bot runtime credential. */
export const chatSlackManagerGrants = pgTable("chat_slack_manager_grants", {
id: uuid("id").primaryKey().defaultRandom(),
companyId: uuid("company_id").notNull().references(() => companies.id, { onDelete: "cascade" }),
userId: text("user_id").notNull(),
slackUserId: text("slack_user_id").notNull(),
workspaceId: text("workspace_id").notNull(),
workspaceName: text("workspace_name").notNull(),
managerAppId: text("manager_app_id").notNull(),
status: text("status").$type<"active" | "revoked" | "reauthorize">().notNull().default("active"),
accessSecretId: uuid("access_secret_id"),
refreshSecretId: uuid("refresh_secret_id"),
revision: integer("revision").notNull().default(0),
rateLimits: jsonb("rate_limits").$type<Record<string, string>>().notNull().default({}),
expiresAt: timestamp("expires_at", { withTimezone: true }),
createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
updatedAt: timestamp("updated_at", { withTimezone: true }).notNull().defaultNow(),
}, t => [
uniqueIndex("chat_slack_manager_grants_company_id_idx").on(t.companyId, t.id),
uniqueIndex("chat_slack_manager_grants_owner_idx").on(t.companyId, t.userId, t.managerAppId, t.workspaceId),
check("chat_slack_manager_grants_status_check", sql`${t.status} in ('active', 'revoked', 'reauthorize')`),
]);
@@ -1,12 +1,14 @@
import { sql } from "drizzle-orm";
import { check, foreignKey, jsonb, pgTable, text, timestamp, uuid } from "drizzle-orm/pg-core";
import type { SlackRegistrationStatus } from "@paperclipai/shared";
import { chatSlackManagerGrants } from "./chat_slack_manager_grants.js";
import { chatEndpoints } from "./chat_channels.js";
/** App provisioning is distinct from installation and runtime credentials. No plaintext secrets. */
export const chatSlackRegistrations = pgTable("chat_slack_registrations", {
endpointId: uuid("endpoint_id").primaryKey(),
companyId: uuid("company_id").notNull(),
managerGrantId: uuid("manager_grant_id"),
requestId: uuid("request_id").notNull(),
status: text("status").$type<SlackRegistrationStatus>().notNull(),
manifest: jsonb("manifest").$type<Record<string, unknown>>().notNull(),
@@ -22,6 +24,7 @@ export const chatSlackRegistrations = pgTable("chat_slack_registrations", {
createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
updatedAt: timestamp("updated_at", { withTimezone: true }).notNull().defaultNow(),
}, t => [
foreignKey({ columns: [t.companyId, t.managerGrantId], foreignColumns: [chatSlackManagerGrants.companyId, chatSlackManagerGrants.id] }),
foreignKey({ columns: [t.companyId, t.endpointId], foreignColumns: [chatEndpoints.companyId, chatEndpoints.id] }).onDelete("cascade"),
check("chat_slack_registration_status_check", sql`${t.status} in ('creating', 'uncertain', 'failed', 'install', 'credentials_saved', 'configured', 'removed')`),
]);
+2
View File
@@ -243,6 +243,8 @@ export { chatVoiceReports } from "./chat_voice_reports.js";
export { chatVoicePhoneLines, chatVoiceInboundCalls } from "./chat_voice_inbound.js";
export * from "./decision_models.js";
export { userCompanyPreferences } from "./user_company_preferences.js";
export { chatSlackManagerGrants } from "./chat_slack_manager_grants.js";
export { aiSubscriptions, aiSubscriptionPrices, aiSubscriptionConnections } from "./ai_subscriptions.js";
export * from "./fast_responses.js";
@@ -1,4 +1,3 @@
// Assemble the four independently built release daemons before npm packing.
// Usage: node packages/paperclip-runner/scripts/stage-release-runner-binaries.mjs MANIFEST.json
// Manifest: {sourceRevision, platforms: {"darwin-arm64": {path, sha256}, ...}, remoteProviderPack: {path, sha256}}.
import { createHash } from "node:crypto";
@@ -31,8 +30,6 @@ function regularFile(path, maximumSize) {
return readFileSync(path);
}
// Production TypeScript contracts are built by the existing producer step.
// Foreign artifacts are data: the assembler never executes another target.
async function metadataContract() {
const { PAPERCLIP_RUNNER_BUILD_METADATA } = await import("../dist/evals/build-metadata.js");
const { parsePaperclipRunnerdBuildMetadata } = await import("../dist/evals/runnerd-artifact.js");
@@ -112,16 +109,12 @@ async function main() {
if (packBytes.length > 512 * 1024 || "sha256:" + createHash("sha256").update(packBytes).digest("hex") !== entry.sha256) throw Error("Remote provider-pack release manifest digest mismatch");
packIdentity = verifyReleaseProviderPack(JSON.parse(packBytes), manifest.sourceRevision);
} else if (daemonOnly) {
// Preserve a qualified same-source Linux pack already materialized by the
// normal producer. It never becomes a Mac provider-pack qualification.
packIdentity = existingReleaseProviderPack(root, manifest.sourceRevision);
}
const platforms = {};
for (const artifact of verified) {
const relative = `${artifact.target}/paperclip-runnerd`, destination = join(root, "dist", "bin", relative);
mkdirSync(dirname(destination), { recursive: true }); copyFileSync(artifact.source, destination); chmodSync(destination, 0o755);
// Copied Mach-O inodes need a fresh ad-hoc signature on macOS. Record the
// resulting packaged bytes, as well as the verified build artifact identity.
if (process.platform === "darwin" && artifact.target.startsWith("darwin-")) {
execFileSync("codesign", ["--force", "--sign", "-", destination], { stdio: "pipe", timeout: 30_000 });
}
@@ -131,7 +124,6 @@ async function main() {
if (packBytes) {
const destination = join(root, "dist", "remote-provider-packs", "linux-x64", "provider-pack.json");
mkdirSync(dirname(destination), { recursive: true });
// Replace the inode so repeat assembly can preserve a read-only manifest.
const staged = `${destination}.staging-${process.pid}`;
try {
writeFileSync(staged, packBytes, { mode: 0o444, flag: "wx" });
@@ -32,8 +32,6 @@ export async function stageBuiltRunnerBinary(packageRoot) {
const executable = process.platform === "win32" ? "paperclip-runnerd.exe" : "paperclip-runnerd";
const source = path.join(packageRoot, "runner", "target", "release", executable);
const binaryRoot = path.join(packageRoot, "dist", "bin");
// Source builds are separate from the source-bound release targets and their
// manifest. The dev supervisor selects this fresh output for its server.
await stageRunnerBinary(source, path.join(binaryRoot, executable));
}
@@ -140,8 +140,6 @@ test("a source rebuild selects fresh dev bytes while preserving release binaries
const copyHostFixture = async (input, output) => {
await copyFile(input, output);
if (process.platform === "darwin") {
// System fixtures can be universal; Cargo release daemons are thin.
// Extract only this host slice before exercising the native header gate.
const slices = execFileSync("/usr/bin/lipo", ["-archs", input], { encoding: "utf8" }).trim().split(/\s+/);
const architecture = slices.find(value => process.arch === "arm64" ? value.startsWith("arm64") : value === "x86_64");
assert.ok(architecture);
@@ -31,8 +31,6 @@ vi.mock("smol-toml", async (importOriginal) => {
...actual,
parse: (...args: Parameters<typeof actual.parse>) => {
const result = actual.parse(...args);
// Exercise both table representations independently of the installed
// parser version while retaining the real TOML values.
setTablePrototypes(result);
return result;
},
@@ -92,8 +92,6 @@ export function trustCodexStartupRoot(codexHome: string, cwd: string): void {
const path = join(codexHome, "config.toml");
const source = existsSync(path) ? readFileSync(path, "utf8") : "";
const config = parse(source);
// Retain the parser's table prototypes so strict candidate comparison also
// works with parsers that return null-prototype TOML tables.
const projects = config.projects ?? parse("");
if (
typeof projects !== "object" ||
@@ -396,7 +396,6 @@ it("publishes spawned runner ownership before waiting for provider startup", asy
});
const opening = bundle.transport.request("thread/start", { cwd: tmpdir(), dynamicTools: codexSemanticToolSpecs() });
try {
// Same-tick recovery must not mutate an already admitted fresh startup.
await expect(bundle.transport.request("thread/read", { threadId: "rejected-duplicate" }))
.rejects.toThrow("PRP provider thread is already started");
await vi.waitFor(() => expect(onSpawn).toHaveBeenCalledOnce());
@@ -2223,7 +2222,6 @@ it("owns blocked Codex home preparation through driver abort without later regis
markPreparationStarted();
await preparationReleased;
preparationContinuedAfterClose = closeSettled;
// A synthetic, credential-free write makes the owned preparation visible.
await mkdir(input.codexHome, { mode: 0o700 });
await writeFile(join(input.codexHome, "preparation-marker"), "fixture preparation drained\n", { mode: 0o600 });
});
@@ -2264,7 +2262,6 @@ it("owns blocked Codex home preparation through driver abort without later regis
.then(value => { openingSettled = true; return { value }; }, error => { openingSettled = true; return { error }; });
try {
await preparationStarted;
// A rejected duplicate must not replace the first admitted startup owner.
await expect(transport.request("thread/start", { cwd: root, dynamicTools: [] }))
.rejects.toThrow("PRP provider thread is already started");
controller.abort(cancelled);
@@ -2863,8 +2860,6 @@ it.each(["stuck", "late-release", "late-release-error", "stuck-release", "cooper
runtimeDirectory, provider: "codex", model: "gpt-test", timeoutMs: 1_000,
environment: { PATH: "", OPENAI_API_KEY: "inert-test-key" },
transportOptions: {
// Registration and launch are external owners; hash real inert bytes
// without executing a daemon, Codex, or an ambient developer binary.
runnerBinary: resolve(import.meta.dirname, "../../package.json"),
codexCommand: resolve(import.meta.dirname, "../../package.json"),
sourceCodexHome: "", runnerProcessLauncher: launch,
@@ -2895,8 +2890,6 @@ it.each(["stuck", "late-release", "late-release-error", "stuck-release", "cooper
expect(cleanup).not.toHaveBeenCalled();
expect((await stat(runtimeDirectory)).isDirectory()).toBe(true);
if (mode === "late-release-error") expect((failure as AggregateError).errors).toContain(releaseError);
// A registration that finishes after the bounded return still releases
// its authority, without retroactively certifying or deleting state.
returnRegistration(registered);
finishRelease();
await vi.advanceTimersByTimeAsync(0);
@@ -1338,7 +1338,6 @@ export interface CapabilityRunnerdCodexTransportOptions {
controlPlaneRegistration?: (
authority: DurablePrpControlPlane,
identity?: DurableRecoveryIdentity,
/** Setup owners abort preparation before draining or releasing its result. */
signal?: AbortSignal,
) => Promise<{
connectUrl?: string;
@@ -4466,8 +4465,6 @@ class DurablePrpCodexTransport implements CodexAppServerTransport {
}
#trackStartup<T>(start: () => Promise<T>): Promise<T> {
// Admit one owner before invoking startup. A duplicate request's rejection
// must never replace the preparation that close is responsible for joining.
if (this.#startupOperation !== null) {
return Promise.reject(new Error("PRP provider thread is already started"));
}
@@ -7108,8 +7105,6 @@ class DurablePrpCodexTransport implements CodexAppServerTransport {
}
await Promise.race([
ready(), this.#failureSignal,
// Readiness is a notification wait, not launch-material preparation.
// Its route owner is released by close; joining it first would cycle.
this.#closedSignal.then(() => { this.#assertStartupOpen(); }),
]);
this.#assertStartupOpen();
@@ -7160,7 +7155,6 @@ export function createCapabilityRunnerdCodexTransport(
export const createRunnerdCodexTransport =
createCapabilityRunnerdCodexTransport;
/** A setup turn uses the same daemon/provider boundary as ordinary native runs. */
export async function probeNativeRunnerEnvironment(options: {
runtimeDirectory: string;
provider: "codex";
@@ -7168,7 +7162,6 @@ export async function probeNativeRunnerEnvironment(options: {
reasoningEffort?: string;
environment: NodeJS.ProcessEnv;
timeoutMs?: number;
/** The selected remote filesystem supplies this cwd; never inspect it on the controller. */
workingDirectory?: string;
transportOptions?: CapabilityRunnerdCodexTransportOptions;
onCodexCredentialRefresh?: (filename: string) => Promise<void>;
@@ -7189,9 +7182,6 @@ export async function probeNativeRunnerEnvironment(options: {
let registrationOperation: Promise<unknown> | undefined;
let registrationCleanupConfirmed = true;
const sourceCodexHome = options.transportOptions?.sourceCodexHome ?? resolveSourceCodexHome(environment);
// Never let an unbound home or an external-sandbox flag admit host state or
// weaken this read-only probe. The normal materializer copies bound auth and
// the managed provider projection into a new daemon-owned Codex home.
delete environment.PAPERCLIP_RUNNER_EXTERNAL_SANDBOX;
environment.HOME = resolve(remoteFilesystemRoot ?? options.runtimeDirectory, "probe-home");
environment.CODEX_HOME = resolve(remoteFilesystemRoot ?? options.runtimeDirectory, "codex-home");
@@ -7310,8 +7300,6 @@ export async function probeNativeRunnerEnvironment(options: {
} finally {
clearTimeout(timer);
controller.abort(failure ?? new Error("Native provider hello probe complete."));
// Preserve private recovery state if the production close cannot confirm
// teardown; callers remove it only after an authoritative receipt.
const teardownErrors: unknown[] = [];
const teardownDeadline = Date.now() + 10_000;
const awaitTeardown = async (pending: Promise<unknown>, detail: string): Promise<void> => {
@@ -441,8 +441,6 @@ beforeEach(() => {
"div",
{ key: routine.key },
createElement("span", null, routine.title),
createElement("button", null, "Run now"),
createElement("button", { role: "switch" }, "On"),
routine.href ? createElement("a", { href: `/PAP${routine.href}` }, "Configure") : null,
routine.defaultDrift?.changedFields.length
? createElement("span", null, `Plugin defaults changed: ${routine.defaultDrift.changedFields.join(", ")}`)
@@ -656,6 +654,46 @@ function mockPersistedWikiSpace(harness: ReturnType<typeof createTestHarness>, s
};
}
function renderWikiPage(): string {
return renderToStaticMarkup(createElement(WikiPage, {
context: { companyId: COMPANY_ID, companyPrefix: "PAP" },
} as never));
}
function captureWikiWrites(harness: ReturnType<typeof createTestHarness>) {
const writes: Array<{ path: string; contents: string }> = [];
harness.ctx.localFolders.writeTextAtomic = async (_companyId, _folderKey, relativePath, contents) => {
writes.push({ path: relativePath, contents });
return harness.ctx.localFolders.status(COMPANY_ID, "wiki-root");
};
return writes;
}
function managedSpaceRow(created: {
space: { id: string; companyId: string; wikiId: string; slug: string; displayName: string; pathPrefix: string | null };
}): Record<string, unknown> {
return {
id: created.space.id,
company_id: created.space.companyId,
wiki_id: created.space.wikiId,
slug: created.space.slug,
display_name: created.space.displayName,
space_type: "local_folder",
folder_mode: "managed_subfolder",
root_folder_key: "wiki-root",
path_prefix: created.space.pathPrefix,
configured_root_path: null,
access_scope: "shared",
owner_user_id: null,
owner_agent_id: null,
team_key: null,
settings: {},
status: "active",
created_at: null,
updated_at: null,
};
}
describe("LLM Wiki plugin scaffold", () => {
it("declares standalone plugin surfaces without core wiki coupling", () => {
expect(manifest.id).toBe("paperclipai.plugin-llm-wiki");
@@ -814,9 +852,7 @@ describe("LLM Wiki plugin scaffold", () => {
it("routes legacy Wiki operations URLs to the History issue table", () => {
mockPathname = "/PAP/wiki/operations";
const markup = renderToStaticMarkup(createElement(WikiPage, {
context: { companyId: COMPANY_ID, companyPrefix: "PAP" },
} as never));
const markup = renderWikiPage();
expect(markup).toContain("Issues table · project-1 · plugin:paperclipai.plugin-llm-wiki:operation");
expect(markup).not.toContain("Recent runs");
@@ -825,9 +861,7 @@ describe("LLM Wiki plugin scaffold", () => {
it("loads AGENTS.md from the Wiki page and exposes an edit affordance", () => {
mockPathname = "/PAP/wiki/page/templates/AGENTS.md";
const markup = renderToStaticMarkup(createElement(WikiPage, {
context: { companyId: COMPANY_ID, companyPrefix: "PAP" },
} as never));
const markup = renderWikiPage();
expect(markup).toContain("AGENTS");
expect(markup).toContain(">AGENTS.md</h1>");
@@ -851,9 +885,7 @@ describe("LLM Wiki plugin scaffold", () => {
sourceRefs: [{ kind: "issue", issueIdentifier: "PAP-FOOTER-1" }],
};
const markup = renderToStaticMarkup(createElement(WikiPage, {
context: { companyId: COMPANY_ID, companyPrefix: "PAP" },
} as never));
const markup = renderWikiPage();
expect(markup).toContain("Current project state.");
expect(markup).not.toContain(">Sources</");
@@ -878,9 +910,7 @@ updated: 2026-05-04
Route sidebar state stays attached to the selected wiki page.
`;
const markup = renderToStaticMarkup(createElement(WikiPage, {
context: { companyId: COMPANY_ID, companyPrefix: "PAP" },
} as never));
const markup = renderWikiPage();
expect(markup).toContain("<summary");
expect(markup).toContain("Properties");
@@ -918,9 +948,7 @@ Wiki links preserve normal browser navigation.
Duplicate headings receive stable suffixes.
`;
const markup = renderToStaticMarkup(createElement(WikiPage, {
context: { companyId: COMPANY_ID, companyPrefix: "PAP" },
} as never));
const markup = renderWikiPage();
expect(markup).toContain('aria-label="On this page"');
expect(markup).toContain('aria-expanded="true"');
@@ -959,9 +987,7 @@ Duplicate headings receive stable suffixes.
checkedAt: new Date().toISOString(),
};
const markup = renderToStaticMarkup(createElement(WikiPage, {
context: { companyId: COMPANY_ID, companyPrefix: "PAP" },
} as never));
const markup = renderWikiPage();
expect(markup).toContain("Repair wiki root folder");
expect(markup).toContain("/tmp/deleted-wiki-root");
@@ -997,9 +1023,7 @@ Duplicate headings receive stable suffixes.
it("renders the maintainer settings without plugin metadata or inline AGENTS.md editing", () => {
mockPathname = "/PAP/wiki/settings/maintainer";
const markup = renderToStaticMarkup(createElement(WikiPage, {
context: { companyId: COMPANY_ID, companyPrefix: "PAP" },
} as never));
const markup = renderWikiPage();
expect(markup).toContain("Wiki Maintainer");
expect(markup).toContain("Adapter: claude local");
@@ -1024,9 +1048,7 @@ Duplicate headings receive stable suffixes.
details: { name: "Wiki Maintainer", status: "pending_approval", adapterType: "claude_local", icon: "book-open", urlKey: "wiki-maintainer" },
};
const markup = renderToStaticMarkup(createElement(WikiPage, {
context: { companyId: COMPANY_ID, companyPrefix: "PAP" },
} as never));
const markup = renderWikiPage();
expect(markup).toContain("pending approval");
expect(markup).toContain("Approve the agent");
@@ -1035,9 +1057,7 @@ Duplicate headings receive stable suffixes.
it("renders root settings as a compact health checklist with the shared path picker", () => {
mockPathname = "/PAP/wiki/settings";
const markup = renderToStaticMarkup(createElement(WikiPage, {
context: { companyId: COMPANY_ID, companyPrefix: "PAP" },
} as never));
const markup = renderWikiPage();
expect(markup).toContain(">Setup</");
expect(markup).toContain("Base Folder");
@@ -1107,9 +1127,7 @@ Duplicate headings receive stable suffixes.
checkedAt: new Date().toISOString(),
};
const markup = renderToStaticMarkup(createElement(WikiPage, {
context: { companyId: COMPANY_ID, companyPrefix: "PAP" },
} as never));
const markup = renderWikiPage();
expect(markup).toContain("configuration errors detected, fix them all?");
expect(markup).toContain("Wiki root folder");
@@ -1132,9 +1150,7 @@ Duplicate headings receive stable suffixes.
},
}];
const markup = renderToStaticMarkup(createElement(WikiPage, {
context: { companyId: COMPANY_ID, companyPrefix: "PAP" },
} as never));
const markup = renderWikiPage();
expect(markup).toContain("Managed Skills");
expect(markup).toContain("skill issue(s) need attention");
@@ -1156,9 +1172,7 @@ Duplicate headings receive stable suffixes.
},
}];
const markup = renderToStaticMarkup(createElement(WikiPage, {
context: { companyId: COMPANY_ID, companyPrefix: "PAP" },
} as never));
const markup = renderWikiPage();
expect(markup).toContain("skill issue(s) need attention");
expect(markup).toContain("LLM Wiki Maintainer differs from the plugin default: SKILL.md.");
@@ -1178,9 +1192,7 @@ Duplicate headings receive stable suffixes.
it("renders project settings as a project picker without managed-resource metadata", () => {
mockPathname = "/PAP/wiki/settings/project";
const markup = renderToStaticMarkup(createElement(WikiPage, {
context: { companyId: COMPANY_ID, companyPrefix: "PAP" },
} as never));
const markup = renderWikiPage();
expect(markup).toContain("Use existing project");
expect(markup).toContain("LLM Wiki");
@@ -1199,9 +1211,7 @@ Duplicate headings receive stable suffixes.
it("renders space settings with health line styling and disabled access controls", () => {
mockPathname = "/PAP/wiki/settings/spaces/default";
const markup = renderToStaticMarkup(createElement(WikiPage, {
context: { companyId: COMPANY_ID, companyPrefix: "PAP" },
} as never));
const markup = renderWikiPage();
expect(markup).toContain("Space folder health checklist");
expect(markup).toContain("left:8px");
@@ -1231,9 +1241,7 @@ Duplicate headings receive stable suffixes.
runs: [],
};
const markup = renderToStaticMarkup(createElement(WikiPage, {
context: { companyId: COMPANY_ID, companyPrefix: "PAP" },
} as never));
const markup = renderWikiPage();
expect(markup).toContain("Agent execution");
expect(markup).toContain("Assigned maintainer");
@@ -1248,7 +1256,7 @@ Duplicate headings receive stable suffixes.
expect(markup).not.toContain("Monthly plugin cap");
});
it("renders managed routines as normal routine rows with run, toggle, and configure controls", () => {
it("passes managed routine titles, bindings, and configuration links to the host list", () => {
mockPathname = "/PAP/wiki/settings/routines";
mockSettingsManagedRoutines = [{
status: "resolved",
@@ -1265,14 +1273,10 @@ Duplicate headings receive stable suffixes.
},
details: { cronExpression: "0 3 * * *" },
}];
const markup = renderToStaticMarkup(createElement(WikiPage, {
context: { companyId: COMPANY_ID, companyPrefix: "PAP" },
} as never));
const markup = renderWikiPage();
expect(markup).toContain("Run LLM Wiki lint");
expect(markup).toContain("Run now");
expect(markup).toContain("Configure");
expect(markup).toContain("role=\"switch\"");
expect(markup).toContain("LLM Wiki · Wiki Maintainer");
expect(markup).toContain("href=\"/PAP/routines/routine-1\"");
});
@@ -1299,9 +1303,7 @@ Duplicate headings receive stable suffixes.
details: { cronExpression: "0 3 * * *" },
}];
const markup = renderToStaticMarkup(createElement(WikiPage, {
context: { companyId: COMPANY_ID, companyPrefix: "PAP" },
} as never));
const markup = renderWikiPage();
expect(markup).toContain("Routine defaults changed");
expect(markup).toContain("Plugin defaults changed: description");
@@ -1319,9 +1321,7 @@ Duplicate headings receive stable suffixes.
details: { name: "Wiki Maintainer", status: "idle", adapterType: "claude_local", icon: "book-open", urlKey: "wiki-maintainer" },
};
const markup = renderToStaticMarkup(createElement(WikiPage, {
context: { companyId: COMPANY_ID, companyPrefix: "PAP" },
} as never));
const markup = renderWikiPage();
expect(markup).toContain("Wiki Maintainer instructions differ from the plugin default: AGENTS.md.");
expect(markup).toContain("Wiki Maintainer instruction defaults changed: AGENTS.md");
@@ -1344,9 +1344,7 @@ Duplicate headings receive stable suffixes.
details: { cronExpression: "0 3 * * *" },
}];
const markup = renderToStaticMarkup(createElement(WikiPage, {
context: { companyId: COMPANY_ID, companyPrefix: "PAP" },
} as never));
const markup = renderWikiPage();
expect(markup).toContain("Routine setup needs repair");
expect(markup).toContain("Fix routines");
@@ -1358,9 +1356,7 @@ Duplicate headings receive stable suffixes.
it("renders legacy lint routes inside the Wiki settings section", () => {
mockPathname = "/PAP/wiki/lint";
const markup = renderToStaticMarkup(createElement(WikiPage, {
context: { companyId: COMPANY_ID, companyPrefix: "PAP" },
} as never));
const markup = renderWikiPage();
expect(markup).toContain("Run lint now");
expect(markup).toContain("Recent lint runs");
@@ -1369,9 +1365,7 @@ Duplicate headings receive stable suffixes.
it("does not expose IDEA.md pattern editing as a settings section", () => {
mockPathname = "/PAP/wiki/settings";
const markup = renderToStaticMarkup(createElement(WikiPage, {
context: { companyId: COMPANY_ID, companyPrefix: "PAP" },
} as never));
const markup = renderWikiPage();
expect(markup).toContain("LLM Wiki settings sections");
expect(markup).not.toContain(">Pattern</span>");
@@ -1381,9 +1375,7 @@ Duplicate headings receive stable suffixes.
it("does not expose plugin capabilities as a settings section", () => {
mockPathname = "/PAP/wiki/settings";
const markup = renderToStaticMarkup(createElement(WikiPage, {
context: { companyId: COMPANY_ID, companyPrefix: "PAP" },
} as never));
const markup = renderWikiPage();
expect(markup).toContain("LLM Wiki settings sections");
expect(markup).not.toContain("Plugin capabilities");
@@ -1392,11 +1384,7 @@ Duplicate headings receive stable suffixes.
it("reconciles managed maintenance routines through stable agent and project refs", async () => {
const harness = createTestHarness({ manifest });
const writes: Array<{ path: string; contents: string }> = [];
harness.ctx.localFolders.writeTextAtomic = async (_companyId, _folderKey, relativePath, contents) => {
writes.push({ path: relativePath, contents });
return harness.ctx.localFolders.status(COMPANY_ID, "wiki-root");
};
const writes = captureWikiWrites(harness);
await plugin.definition.setup(harness.ctx);
@@ -1651,11 +1639,7 @@ Duplicate headings receive stable suffixes.
const harness = createTestHarness({ manifest });
const issue = paperclipIssue();
harness.seed({ issues: [issue] });
const writes: Array<{ path: string; contents: string }> = [];
harness.ctx.localFolders.writeTextAtomic = async (_companyId, _folderKey, relativePath, contents) => {
writes.push({ path: relativePath, contents });
return harness.ctx.localFolders.status(COMPANY_ID, "wiki-root");
};
const writes = captureWikiWrites(harness);
await plugin.definition.setup(harness.ctx);
await harness.emit("issue.created", { identifier: issue.identifier }, {
@@ -1674,11 +1658,7 @@ Duplicate headings receive stable suffixes.
const harness = createTestHarness({ manifest });
const issue = paperclipIssue();
harness.seed({ issues: [issue] });
const writes: Array<{ path: string; contents: string }> = [];
harness.ctx.localFolders.writeTextAtomic = async (_companyId, _folderKey, relativePath, contents) => {
writes.push({ path: relativePath, contents });
return harness.ctx.localFolders.status(COMPANY_ID, "wiki-root");
};
const writes = captureWikiWrites(harness);
await plugin.definition.setup(harness.ctx);
const policy = await harness.performAction<{ enabled: boolean; sources: { issues: boolean; comments: boolean; documents: boolean } }>(
@@ -2768,11 +2748,7 @@ Duplicate headings receive stable suffixes.
it("bootstraps required local wiki files through the local folder API", async () => {
const harness = createTestHarness({ manifest });
const writes: Array<{ path: string; contents: string }> = [];
harness.ctx.localFolders.writeTextAtomic = async (_companyId, _folderKey, relativePath, contents) => {
writes.push({ path: relativePath, contents });
return harness.ctx.localFolders.status(COMPANY_ID, "wiki-root");
};
const writes = captureWikiWrites(harness);
await plugin.definition.setup(harness.ctx);
const result = await harness.performAction<{ writtenFiles: string[]; managedSkills: WikiSkillResource[] }>("bootstrap-root", {
@@ -3009,11 +2985,7 @@ Duplicate headings receive stable suffixes.
it("captures raw sources into local files and plugin metadata", async () => {
const harness = createTestHarness({ manifest });
const writes: Array<{ path: string; contents: string }> = [];
harness.ctx.localFolders.writeTextAtomic = async (_companyId, _folderKey, relativePath, contents) => {
writes.push({ path: relativePath, contents });
return harness.ctx.localFolders.status(COMPANY_ID, "wiki-root");
};
const writes = captureWikiWrites(harness);
await plugin.definition.setup(harness.ctx);
const result = await harness.performAction<{ rawPath: string; hash: string }>("capture-source", {
@@ -3031,11 +3003,7 @@ Duplicate headings receive stable suffixes.
it("preserves manual source ingest for non-default spaces while refusing Paperclip distillation there", async () => {
const harness = createTestHarness({ manifest });
const writes: Array<{ path: string; contents: string }> = [];
harness.ctx.localFolders.writeTextAtomic = async (_companyId, _folderKey, relativePath, contents) => {
writes.push({ path: relativePath, contents });
return harness.ctx.localFolders.status(COMPANY_ID, "wiki-root");
};
const writes = captureWikiWrites(harness);
harness.seed({
agents: [wikiMaintainerAgent()],
projects: [existingProject()],
@@ -3057,26 +3025,7 @@ Duplicate headings receive stable suffixes.
companyId: COMPANY_ID,
displayName: "Team Research",
});
spaces.set(created.space.slug, {
id: created.space.id,
company_id: created.space.companyId,
wiki_id: created.space.wikiId,
slug: created.space.slug,
display_name: created.space.displayName,
space_type: "local_folder",
folder_mode: "managed_subfolder",
root_folder_key: "wiki-root",
path_prefix: created.space.pathPrefix,
configured_root_path: null,
access_scope: "shared",
owner_user_id: null,
owner_agent_id: null,
team_key: null,
settings: {},
status: "active",
created_at: null,
updated_at: null,
});
spaces.set(created.space.slug, managedSpaceRow(created));
const source = await harness.performAction<{ rawPath: string; spaceSlug: string }>("capture-source", {
companyId: COMPANY_ID,
@@ -3299,26 +3248,7 @@ Duplicate headings receive stable suffixes.
companyId: COMPANY_ID,
displayName: "Research Space",
});
spaces.set(created.space.slug, {
id: created.space.id,
company_id: created.space.companyId,
wiki_id: created.space.wikiId,
slug: created.space.slug,
display_name: created.space.displayName,
space_type: "local_folder",
folder_mode: "managed_subfolder",
root_folder_key: "wiki-root",
path_prefix: created.space.pathPrefix,
configured_root_path: null,
access_scope: "shared",
owner_user_id: null,
owner_agent_id: null,
team_key: null,
settings: {},
status: "active",
created_at: null,
updated_at: null,
});
spaces.set(created.space.slug, managedSpaceRow(created));
await harness.performAction("bootstrap-space", {
companyId: COMPANY_ID,
spaceSlug: created.space.slug,
@@ -3364,6 +3294,8 @@ Duplicate headings receive stable suffixes.
const pageWrites = harness.dbExecutes.filter((execute) => execute.sql.includes("wiki_pages"));
const sourceWrites = harness.dbExecutes.filter((execute) => execute.sql.includes("wiki_sources"));
expect(pageWrites).toHaveLength(4);
expect(sourceWrites).toHaveLength(2);
expect(pageWrites.every((write) => write.sql.includes("space_id"))).toBe(true);
expect(sourceWrites.every((write) => write.sql.includes("space_id"))).toBe(true);
});
@@ -3371,11 +3303,7 @@ Duplicate headings receive stable suffixes.
it("ingests source metadata and creates a hidden plugin-operation issue", async () => {
const harness = createTestHarness({ manifest });
harness.seed({ agents: [wikiMaintainerAgent()] });
const writes: Array<{ path: string; contents: string }> = [];
harness.ctx.localFolders.writeTextAtomic = async (_companyId, _folderKey, relativePath, contents) => {
writes.push({ path: relativePath, contents });
return harness.ctx.localFolders.status(COMPANY_ID, "wiki-root");
};
const writes = captureWikiWrites(harness);
await plugin.definition.setup(harness.ctx);
const result = await harness.performAction<{
@@ -3429,11 +3357,7 @@ Duplicate headings receive stable suffixes.
it("rejects oversized source capture before raw writes or operation creation", async () => {
const harness = createTestHarness({ manifest, config: { maxSourceBytes: 16 } });
harness.seed({ agents: [wikiMaintainerAgent()] });
const writes: Array<{ path: string; contents: string }> = [];
harness.ctx.localFolders.writeTextAtomic = async (_companyId, _folderKey, relativePath, contents) => {
writes.push({ path: relativePath, contents });
return harness.ctx.localFolders.status(COMPANY_ID, "wiki-root");
};
const writes = captureWikiWrites(harness);
await plugin.definition.setup(harness.ctx);
await expect(harness.performAction("ingest-source", {
@@ -3568,26 +3492,7 @@ Duplicate headings receive stable suffixes.
companyId: COMPANY_ID,
displayName: "Research Space",
});
spaces.set(created.space.slug, {
id: created.space.id,
company_id: created.space.companyId,
wiki_id: created.space.wikiId,
slug: created.space.slug,
display_name: created.space.displayName,
space_type: "local_folder",
folder_mode: "managed_subfolder",
root_folder_key: "wiki-root",
path_prefix: created.space.pathPrefix,
configured_root_path: null,
access_scope: "shared",
owner_user_id: null,
owner_agent_id: null,
team_key: null,
settings: {},
status: "active",
created_at: null,
updated_at: null,
});
spaces.set(created.space.slug, managedSpaceRow(created));
const result = await harness.performAction<{
operationId: string;
@@ -3669,6 +3574,13 @@ Duplicate headings receive stable suffixes.
it("starts query sessions, records run ids, and forwards session events to plugin streams", async () => {
const harness = createTestHarness({ manifest });
harness.seed({ agents: [wikiMaintainerAgent()] });
let issuedRunId: string | undefined;
const originalSendMessage = harness.ctx.agents.sessions.sendMessage.bind(harness.ctx.agents.sessions);
harness.ctx.agents.sessions.sendMessage = async (...args) => {
const receipt = await originalSendMessage(...args);
issuedRunId = receipt.runId;
return receipt;
};
const streamEvents: unknown[] = [];
harness.ctx.streams.emit = (_channel, event) => {
streamEvents.push(event);
@@ -3689,7 +3601,15 @@ Duplicate headings receive stable suffixes.
expect(result.querySessionId).toBe(result.operationId);
expect(result.channel).toBe(`llm-wiki:query:${result.operationId}`);
expect(harness.dbExecutes.some((execute) => execute.sql.includes("wiki_query_sessions"))).toBe(true);
expect(harness.dbExecutes.some((execute) => execute.sql.includes("run_ids"))).toBe(true);
expect(issuedRunId).toEqual(expect.any(String));
expect(issuedRunId).not.toBe("");
expect(result.runId).toBe(issuedRunId);
const runUpdate = harness.dbExecutes.find((execute) =>
/UPDATE .*wiki_operations/.test(execute.sql) && execute.sql.includes("run_ids"),
);
expect(runUpdate?.params?.slice(0, 4)).toEqual([
COMPANY_ID, result.operationId, "running", JSON.stringify([issuedRunId]),
]);
harness.simulateSessionEvent(result.sessionId, {
runId: result.runId,
@@ -3722,11 +3642,7 @@ Duplicate headings receive stable suffixes.
it("files a streamed query answer as a page through a hidden file-as-page operation", async () => {
const harness = createTestHarness({ manifest });
harness.seed({ agents: [wikiMaintainerAgent()] });
const writes: Array<{ path: string; contents: string }> = [];
harness.ctx.localFolders.writeTextAtomic = async (_companyId, _folderKey, relativePath, contents) => {
writes.push({ path: relativePath, contents });
return harness.ctx.localFolders.status(COMPANY_ID, "wiki-root");
};
const writes = captureWikiWrites(harness);
await plugin.definition.setup(harness.ctx);
const result = await harness.performAction<{ path: string; operationId: string; page: { revisionId: string } }>(
@@ -763,11 +763,6 @@ describe("AppDefinition catalog", () => {
APP_DEFINITIONS.find((app) => app.slug === "linear")?.methods[0]?.defaults
?.scopesHint,
).toEqual(["read", "write"]));
it("requests Hugging Face MCP read, contribution and job scopes", () =>
expect(
APP_DEFINITIONS.find((app) => app.slug === "hugging-face")?.methods[0]
?.defaults?.scopesHint,
).toEqual(["read-mcp", "read-repos", "contribute-repos", "jobs"]));
it("defaults every new connection action to allowed except Enterpret writes", () => {
for (const app of APP_DEFINITIONS)
for (const method of app.methods) {
@@ -1327,21 +1322,6 @@ describe("AppDefinition catalog", () => {
?.available,
).toBe(false);
});
it("enforces method and field invariants", () => {
for (const app of APP_DEFINITIONS)
for (const method of app.methods) {
if (
method.auth === "api_key" &&
(method.purpose ?? "tool") !== "channel"
)
expect(method.keyPlacement).toBeTruthy();
if (method.auth === "oauth")
expect(method.ownershipModes.length).toBeGreaterThan(0);
for (const field of method.credentialFields ?? [])
if (field.required && field.type !== "checkbox")
expect(field.placeholder).toBeTruthy();
}
});
});
+44 -1
View File
@@ -22,7 +22,7 @@ export function buildSlackAppManifest(input: {
redirectUri?: string;
}) {
return {
display_information: { name: input.app.appName },
display_information: { name: input.app.appName, description: `Talk to ${input.agentName} and manage work in Paperclip.`.slice(0, 140) },
features: {
app_home: { home_tab_enabled: false, messages_tab_enabled: true, messages_tab_read_only_enabled: false },
agent_view: { agent_description: "Work with a Paperclip agent in a task-backed conversation." },
@@ -60,6 +60,7 @@ export const slackRegistrationStateSchema = z.object({
status: slackRegistrationStatusSchema,
appId: z.string().nullable().optional(),
managementUrl: z.string().url().nullable().optional(),
managerGrantId: z.string().uuid().nullable().optional(),
errorCode: z.string().nullable().optional(),
}).strict();
export type SlackRegistrationState = z.infer<typeof slackRegistrationStateSchema>;
@@ -79,11 +80,33 @@ export const slackAccountStateSchema = z.object({
}).strict();
export type SlackAccountState = z.infer<typeof slackAccountStateSchema>;
export const slackInstallAuthorizationSchema = z.object({ authorizationUrl: z.string().url(), expiresAt: z.string().datetime() });
export const slackManagerAuthorizationSchema = slackInstallAuthorizationSchema.extend({ handoff: z.object({ kind: z.literal("paperclip_cloud"), session: z.string().min(16).max(512) }).optional() });
export type SlackManagerAuthorization = z.infer<typeof slackManagerAuthorizationSchema>;
export type SlackInstallAuthorization = z.infer<typeof slackInstallAuthorizationSchema>;
export const slackSetupActionSchema = z.object({}).strict();
export const slackTestMessageSchema = z.object({
requestId: z.string().uuid(),
slackUserId: z.string().regex(/^[UW][A-Z0-9]+$/).optional(),
accountCursor: z.string().min(1).max(512).optional(),
}).strict();
export type SlackTestMessageInput = z.infer<typeof slackTestMessageSchema>;
export const slackTestMessageResultSchema = z.discriminatedUnion("status", [
z.object({ status: z.literal("sent"), slackUrl: z.string().url() }).strict(),
z.object({ status: z.literal("connection_required"), accounts: z.array(z.object({
id: z.string(), name: z.string(),
}).strict()), nextCursor: z.string().nullable() }).strict(),
z.object({ status: z.literal("connection_pending"), principalId: z.string().uuid(), expiresAt: z.string().datetime() }).strict(),
]);
export type SlackTestMessageResult = z.infer<typeof slackTestMessageResultSchema>;
export function slackRegistrationErrorMessage(code: string): string {
const messages: Record<string, string> = {
slack_managed_unavailable: "Managed Slack setup is unavailable. Try again later or use your own app before creation starts.",
slack_manager_reauthorize: "Reconnect your Slack workspace to continue setting up this agent.",
slack_approval_pending: "Slack is waiting for your workspace administrator to approve this app.",
slack_approval_required: "Your Slack workspace requires approval. Continue in Slack to request it.",
slack_approval_denied: "Your Slack administrator declined this installation. Contact them to continue.",
slack_configuration_token_invalid: "Slack rejected the app configuration access token. Generate a new access token and try again.",
slack_manifest_invalid: "Slack rejected this app configuration. Check the app details or use manual setup.",
slack_manifest_update_pending: "Your Slack app is saved, but its event settings still need to be applied. Enter an app configuration access token to retry configuring the same app.",
@@ -96,9 +119,29 @@ export function slackRegistrationErrorMessage(code: string): string {
slack_install_identity_mismatch: "Slack returned a different app, workspace, or bot. Install the app created for this connection.",
slack_install_scopes_missing: "Slack did not grant all required bot permissions. Install the app again and approve its requested permissions.",
slack_bot_already_connected: "This Slack bot is already connected to Paperclip. Resume its existing connection or use a different app.",
slack_install_token_invalid: "Slack rejected the saved bot credentials. Continue in Slack to authorize this app again.",
slack_configuration_incomplete: "The app is installed, but Paperclip could not finish connecting it. Retry connecting the saved installation.",
slack_install_account_missing: "Slack did not identify your account. Authorize the same app again to connect your Slack account.",
slack_install_account_conflict: "This Slack account already has an existing link. Manage account links in connection settings, or authorize with your own Slack account.",
};
return messages[code] ?? "Slack setup could not be completed. Resume setup and try again.";
}
/** Persisted legacy values keep their original meaning. Missing means manual. */
export type SlackSetupMethod = "managed" | "automatic" | "manual" | "existing";
export function isProvisionedSlackSetup(method: string | undefined): boolean {
return method === "automatic" || method === "managed";
}
export const SLACK_MANAGER_SCOPES = ["app_configurations:read", "app_configurations:write", "managed_apps:install"] as const;
export const slackSetupOptionsSchema = z.object({
managedAvailable: z.boolean(),
defaultMethod: z.enum(["managed", "automatic"]),
workspaces: z.array(z.object({ grantId: z.string().uuid(), workspaceId: z.string(), workspaceName: z.string(), userId: z.string() })),
});
export type SlackSetupOptions = z.infer<typeof slackSetupOptionsSchema>;
export const slackManagedProvisionSchema = z.object({
requestId: z.string().uuid(), grantId: z.string().uuid(), confirmedNoAppCreated: z.boolean().optional(), reconnect: z.boolean().optional(),
}).strict();
export type SlackManagedProvisionInput = z.infer<typeof slackManagedProvisionSchema>;
export const slackManagedResultSchema = z.object({ authorization: slackInstallAuthorizationSchema.optional() });
export type SlackManagedResult = z.infer<typeof slackManagedResultSchema>;
+4 -2
View File
@@ -190,7 +190,8 @@ export interface SlackAppConfiguration {
}
export interface ChatEndpointSetupState {
slackSetupMethod?: "automatic" | "manual" | "existing";
slackSetupMethod?: "managed" | "automatic" | "manual" | "existing";
slackManagerError?: string;
slackRegistration?: import("../slack-app-manifest.js").SlackRegistrationState;
/** Provider-confirmed app icon outcome; configuration tokens are never retained. */
slackAvatar?: import("../slack-app-manifest.js").SlackAvatarState;
@@ -508,10 +509,11 @@ export interface CreateChatEndpointInput {
applicationId?: string;
name?: string;
slackApp?: SlackAppConfiguration;
slackSetupMethod?: "managed" | "automatic" | "manual" | "existing";
}
export interface UpdateChatEndpointInput {
slackSetupMethod?: "automatic" | "manual" | "existing";
slackSetupMethod?: "managed" | "automatic" | "manual" | "existing";
slackApp?: SlackAppConfiguration;
communicationInstructions?: string;
allowDirectMessages?: boolean;
@@ -80,9 +80,10 @@ export const createChatEndpointSchema = z
applicationId: z.string().uuid().optional(),
name: z.string().trim().min(1).max(160).optional(),
slackApp: slackAppConfigurationSchema.optional(),
slackSetupMethod: z.enum(["managed", "automatic", "manual", "existing"]).optional(),
})
.strict()
.refine(value => !value.slackApp || value.provider === "slack", {
.refine(value => (!value.slackApp && !value.slackSetupMethod) || value.provider === "slack", {
message: "Slack app details only apply to Slack connections", path: ["slackApp"],
});
@@ -90,7 +91,7 @@ export const updateChatEndpointSchema = z
.object({
communicationInstructions: multilineTextSchema.pipe(z.string().trim().max(4000)).optional(),
slackApp: slackAppConfigurationSchema.optional(),
slackSetupMethod: z.enum(["automatic", "manual", "existing"]).optional(),
slackSetupMethod: z.enum(["managed", "automatic", "manual", "existing"]).optional(),
allowDirectMessages: z.boolean().optional(),
requireAtMention: z.boolean().optional(),
allowGroupChats: z.boolean().optional(),
@@ -7,7 +7,7 @@ import { resolveCanonicalWorktreeSeedSource } from "./worktree-seed-source.js";
const cleanup: string[] = [];
function makeInstance(prefix: string, instanceId: string) {
const cwd = fs.mkdtempSync(path.join(os.tmpdir(), prefix));
const cwd = fs.mkdtempSync(path.join(fs.realpathSync(os.tmpdir()), prefix));
cleanup.push(cwd);
const configDir = path.join(cwd, ".paperclip");
const configPath = path.join(configDir, "config.json");
@@ -22,7 +22,7 @@ function makeInstance(prefix: string, instanceId: string) {
* names its instance by directory and has no adjacent .env.
*/
function makeInstanceRoot(instanceId: string) {
const home = fs.mkdtempSync(path.join(os.tmpdir(), "paperclip-seed-home-"));
const home = fs.mkdtempSync(path.join(fs.realpathSync(os.tmpdir()), "paperclip-seed-home-"));
cleanup.push(home);
const configDir = path.join(home, "instances", instanceId);
fs.mkdirSync(configDir, { recursive: true });
@@ -33,7 +33,7 @@ function makeInstanceRoot(instanceId: string) {
/** A managed project checkout: a plain clone with no `.paperclip` of its own. */
function makePlainCheckout() {
const cwd = fs.mkdtempSync(path.join(os.tmpdir(), "paperclip-seed-checkout-"));
const cwd = fs.mkdtempSync(path.join(fs.realpathSync(os.tmpdir()), "paperclip-seed-checkout-"));
cleanup.push(cwd);
return cwd;
}