mirror of
https://github.com/windmill-labs/windmill.git
synced 2026-10-13 00:03:00 +00:00
* feat(ai-sessions): share session artifacts with the workspace by link Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Pyjp67oR269QAx3b4yf4oH * chore: cache the shared artifact queries for offline sqlx Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Pyjp67oR269QAx3b4yf4oH * fix: replace a literal NUL byte in the shared artifact body limit comment Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Pyjp67oR269QAx3b4yf4oH * test: pin that a shared artifact is confined to its workspace's path Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Pyjp67oR269QAx3b4yf4oH * fix: sanitize shared artifact markdown and validate the artifact id on every route The shared page renders another member's markdown, so ArtifactBody now runs the repo's rehype-raw + rehype-sanitize chain with the chat's link renderer on top; only the session viewer opts into the chat code block (mermaid, apply button). The link renderer keeps a link's text when its href is empty or unsafe, and the scheme check moves to a tested helper. The status route checks artifact_id like share does, so a NUL is a 400 rather than a 500. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Pyjp67oR269QAx3b4yf4oH * fix(ai-sessions): say which way re-sharing moves an artifact link The popover offered "Update to v1" when a v2 link was open on a pinned v1, which reads as if v1 were newer. Each direction now has its own sentence and action: a newer version on screen updates the link, an older one shares that version instead, a rename updates the name. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
33 lines
1.6 KiB
SQL
33 lines
1.6 KiB
SQL
-- A copy of an AI session artifact that its author explicitly shared with the workspace.
|
|
-- Artifacts otherwise live only in the author's browser; this row exists only while the
|
|
-- share does, and the monitor deletes it once `shared_at` falls outside
|
|
-- AI_SHARED_ARTIFACT_RETENTION_SECS.
|
|
CREATE TABLE ai_shared_artifact (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
workspace_id VARCHAR(50) NOT NULL REFERENCES workspace(id) ON DELETE CASCADE,
|
|
-- The browser-side artifact id. Unique per author so sharing the same artifact again
|
|
-- moves its one link forward rather than minting a second one.
|
|
artifact_id VARCHAR(255) NOT NULL,
|
|
email VARCHAR(255) NOT NULL,
|
|
created_by VARCHAR(255) NOT NULL,
|
|
name VARCHAR(255) NOT NULL,
|
|
kind VARCHAR(10) NOT NULL CHECK (kind IN ('md', 'html')),
|
|
version INTEGER NOT NULL,
|
|
content TEXT NOT NULL,
|
|
-- Reset on every re-share: retention counts from the last time the author shared it.
|
|
shared_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
|
UNIQUE (workspace_id, email, artifact_id)
|
|
);
|
|
|
|
CREATE INDEX idx_ai_shared_artifact_shared_at ON ai_shared_artifact (shared_at);
|
|
|
|
GRANT ALL ON ai_shared_artifact TO windmill_admin;
|
|
GRANT ALL ON ai_shared_artifact TO windmill_user;
|
|
|
|
-- The handlers go through the raw pool and scope every query to the workspace themselves.
|
|
-- An admin-only policy is the backstop for a future query that reaches this table through
|
|
-- UserDB.
|
|
ALTER TABLE ai_shared_artifact ENABLE ROW LEVEL SECURITY;
|
|
|
|
CREATE POLICY admin_policy ON ai_shared_artifact FOR ALL TO windmill_admin USING (true);
|