// Code generated by sqlc. DO NOT EDIT. // versions: // sqlc v1.31.1 // source: skill.sql package db import ( "context" "github.com/jackc/pgx/v5/pgtype" ) const addAgentSkill = `-- name: AddAgentSkill :exec INSERT INTO agent_skill (agent_id, skill_id) VALUES ($1, $2) ON CONFLICT DO NOTHING ` type AddAgentSkillParams struct { AgentID pgtype.UUID `json:"agent_id"` SkillID pgtype.UUID `json:"skill_id"` } func (q *Queries) AddAgentSkill(ctx context.Context, arg AddAgentSkillParams) error { _, err := q.db.Exec(ctx, addAgentSkill, arg.AgentID, arg.SkillID) return err } const createSkill = `-- name: CreateSkill :one INSERT INTO skill (workspace_id, name, description, content, config, created_by) VALUES ($1, $2, $3, $4, $5, $6) RETURNING id, workspace_id, name, description, content, config, created_by, created_at, updated_at, plugin_installation_id ` type CreateSkillParams struct { WorkspaceID pgtype.UUID `json:"workspace_id"` Name string `json:"name"` Description string `json:"description"` Content string `json:"content"` Config []byte `json:"config"` CreatedBy pgtype.UUID `json:"created_by"` } func (q *Queries) CreateSkill(ctx context.Context, arg CreateSkillParams) (Skill, error) { row := q.db.QueryRow(ctx, createSkill, arg.WorkspaceID, arg.Name, arg.Description, arg.Content, arg.Config, arg.CreatedBy, ) var i Skill err := row.Scan( &i.ID, &i.WorkspaceID, &i.Name, &i.Description, &i.Content, &i.Config, &i.CreatedBy, &i.CreatedAt, &i.UpdatedAt, &i.PluginInstallationID, ) return i, err } const deleteSkill = `-- name: DeleteSkill :exec DELETE FROM skill WHERE id = $1 AND workspace_id = $2 ` type DeleteSkillParams struct { ID pgtype.UUID `json:"id"` WorkspaceID pgtype.UUID `json:"workspace_id"` } // Defense-in-depth: workspace_id is a SQL-layer tenant guard. See DeleteIssue. func (q *Queries) DeleteSkill(ctx context.Context, arg DeleteSkillParams) error { _, err := q.db.Exec(ctx, deleteSkill, arg.ID, arg.WorkspaceID) return err } const deleteSkillFile = `-- name: DeleteSkillFile :exec DELETE FROM skill_file WHERE id = $1 ` func (q *Queries) DeleteSkillFile(ctx context.Context, id pgtype.UUID) error { _, err := q.db.Exec(ctx, deleteSkillFile, id) return err } const deleteSkillFilesBySkill = `-- name: DeleteSkillFilesBySkill :exec DELETE FROM skill_file WHERE skill_id = $1 ` func (q *Queries) DeleteSkillFilesBySkill(ctx context.Context, skillID pgtype.UUID) error { _, err := q.db.Exec(ctx, deleteSkillFilesBySkill, skillID) return err } const getSkill = `-- name: GetSkill :one SELECT id, workspace_id, name, description, content, config, created_by, created_at, updated_at, plugin_installation_id FROM skill WHERE id = $1 ` func (q *Queries) GetSkill(ctx context.Context, id pgtype.UUID) (Skill, error) { row := q.db.QueryRow(ctx, getSkill, id) var i Skill err := row.Scan( &i.ID, &i.WorkspaceID, &i.Name, &i.Description, &i.Content, &i.Config, &i.CreatedBy, &i.CreatedAt, &i.UpdatedAt, &i.PluginInstallationID, ) return i, err } const getSkillByWorkspaceAndName = `-- name: GetSkillByWorkspaceAndName :one SELECT id, workspace_id, name, description, content, config, created_by, created_at, updated_at, plugin_installation_id FROM skill WHERE workspace_id = $1 AND name = $2 ` type GetSkillByWorkspaceAndNameParams struct { WorkspaceID pgtype.UUID `json:"workspace_id"` Name string `json:"name"` } // Used by skill import and runtime-local skill discovery to reuse a workspace // skill by name rather than violating UNIQUE(workspace_id, name). func (q *Queries) GetSkillByWorkspaceAndName(ctx context.Context, arg GetSkillByWorkspaceAndNameParams) (Skill, error) { row := q.db.QueryRow(ctx, getSkillByWorkspaceAndName, arg.WorkspaceID, arg.Name) var i Skill err := row.Scan( &i.ID, &i.WorkspaceID, &i.Name, &i.Description, &i.Content, &i.Config, &i.CreatedBy, &i.CreatedAt, &i.UpdatedAt, &i.PluginInstallationID, ) return i, err } const getSkillFile = `-- name: GetSkillFile :one SELECT id, skill_id, path, content, created_at, updated_at FROM skill_file WHERE id = $1 ` func (q *Queries) GetSkillFile(ctx context.Context, id pgtype.UUID) (SkillFile, error) { row := q.db.QueryRow(ctx, getSkillFile, id) var i SkillFile err := row.Scan( &i.ID, &i.SkillID, &i.Path, &i.Content, &i.CreatedAt, &i.UpdatedAt, ) return i, err } const getSkillInWorkspace = `-- name: GetSkillInWorkspace :one SELECT id, workspace_id, name, description, content, config, created_by, created_at, updated_at, plugin_installation_id FROM skill WHERE id = $1 AND workspace_id = $2 ` type GetSkillInWorkspaceParams struct { ID pgtype.UUID `json:"id"` WorkspaceID pgtype.UUID `json:"workspace_id"` } func (q *Queries) GetSkillInWorkspace(ctx context.Context, arg GetSkillInWorkspaceParams) (Skill, error) { row := q.db.QueryRow(ctx, getSkillInWorkspace, arg.ID, arg.WorkspaceID) var i Skill err := row.Scan( &i.ID, &i.WorkspaceID, &i.Name, &i.Description, &i.Content, &i.Config, &i.CreatedBy, &i.CreatedAt, &i.UpdatedAt, &i.PluginInstallationID, ) return i, err } const listAgentSkillNamesByAgentIDs = `-- name: ListAgentSkillNamesByAgentIDs :many SELECT ask.agent_id, s.name FROM agent_skill ask JOIN skill s ON s.id = ask.skill_id WHERE ask.agent_id = ANY($1::uuid[]) AND ask.enabled = TRUE ORDER BY ask.agent_id, s.name ASC ` type ListAgentSkillNamesByAgentIDsRow struct { AgentID pgtype.UUID `json:"agent_id"` Name string `json:"name"` } func (q *Queries) ListAgentSkillNamesByAgentIDs(ctx context.Context, agentIds []pgtype.UUID) ([]ListAgentSkillNamesByAgentIDsRow, error) { rows, err := q.db.Query(ctx, listAgentSkillNamesByAgentIDs, agentIds) if err != nil { return nil, err } defer rows.Close() items := []ListAgentSkillNamesByAgentIDsRow{} for rows.Next() { var i ListAgentSkillNamesByAgentIDsRow if err := rows.Scan(&i.AgentID, &i.Name); err != nil { return nil, err } items = append(items, i) } if err := rows.Err(); err != nil { return nil, err } return items, nil } const listAgentSkillSummaries = `-- name: ListAgentSkillSummaries :many SELECT s.id, s.workspace_id, s.name, s.description, s.config, s.created_by, s.created_at, s.updated_at, ask.enabled FROM skill s JOIN agent_skill ask ON ask.skill_id = s.id WHERE ask.agent_id = $1 ORDER BY s.name ASC ` type ListAgentSkillSummariesRow struct { ID pgtype.UUID `json:"id"` WorkspaceID pgtype.UUID `json:"workspace_id"` Name string `json:"name"` Description string `json:"description"` Config []byte `json:"config"` CreatedBy pgtype.UUID `json:"created_by"` CreatedAt pgtype.Timestamptz `json:"created_at"` UpdatedAt pgtype.Timestamptz `json:"updated_at"` Enabled bool `json:"enabled"` } // Summary variant for the agent skills list endpoint — omits `content` for // the same reason as ListSkillSummariesByWorkspace. func (q *Queries) ListAgentSkillSummaries(ctx context.Context, agentID pgtype.UUID) ([]ListAgentSkillSummariesRow, error) { rows, err := q.db.Query(ctx, listAgentSkillSummaries, agentID) if err != nil { return nil, err } defer rows.Close() items := []ListAgentSkillSummariesRow{} for rows.Next() { var i ListAgentSkillSummariesRow if err := rows.Scan( &i.ID, &i.WorkspaceID, &i.Name, &i.Description, &i.Config, &i.CreatedBy, &i.CreatedAt, &i.UpdatedAt, &i.Enabled, ); err != nil { return nil, err } items = append(items, i) } if err := rows.Err(); err != nil { return nil, err } return items, nil } const listAgentSkills = `-- name: ListAgentSkills :many SELECT s.id, s.workspace_id, s.name, s.description, s.content, s.config, s.created_by, s.created_at, s.updated_at, s.plugin_installation_id FROM skill s JOIN agent_skill ask ON ask.skill_id = s.id WHERE ask.agent_id = $1 AND ask.enabled = TRUE ORDER BY s.name ASC ` // Agent-Skill junction func (q *Queries) ListAgentSkills(ctx context.Context, agentID pgtype.UUID) ([]Skill, error) { rows, err := q.db.Query(ctx, listAgentSkills, agentID) if err != nil { return nil, err } defer rows.Close() items := []Skill{} for rows.Next() { var i Skill if err := rows.Scan( &i.ID, &i.WorkspaceID, &i.Name, &i.Description, &i.Content, &i.Config, &i.CreatedBy, &i.CreatedAt, &i.UpdatedAt, &i.PluginInstallationID, ); err != nil { return nil, err } items = append(items, i) } if err := rows.Err(); err != nil { return nil, err } return items, nil } const listAgentSkillsByIDs = `-- name: ListAgentSkillsByIDs :many SELECT s.id, s.workspace_id, s.name, s.description, s.content, s.config, s.created_by, s.created_at, s.updated_at, s.plugin_installation_id FROM skill s JOIN agent_skill ask ON ask.skill_id = s.id WHERE ask.agent_id = $1 AND ask.enabled = TRUE AND s.id = ANY($2::uuid[]) ORDER BY s.name ASC ` type ListAgentSkillsByIDsParams struct { AgentID pgtype.UUID `json:"agent_id"` SkillIds []pgtype.UUID `json:"skill_ids"` } // Scoped variant of ListAgentSkills: the same junction predicate, narrowed to // a set of requested skill IDs. The skill-bundle resolve path asks for one // skill per request, so loading the agent's whole set there costs a full read // and hash of every skill on every request. The junction predicate is also the // authorization: an ID the agent does not have enabled simply returns no row, // which the caller reports as not-found. func (q *Queries) ListAgentSkillsByIDs(ctx context.Context, arg ListAgentSkillsByIDsParams) ([]Skill, error) { rows, err := q.db.Query(ctx, listAgentSkillsByIDs, arg.AgentID, arg.SkillIds) if err != nil { return nil, err } defer rows.Close() items := []Skill{} for rows.Next() { var i Skill if err := rows.Scan( &i.ID, &i.WorkspaceID, &i.Name, &i.Description, &i.Content, &i.Config, &i.CreatedBy, &i.CreatedAt, &i.UpdatedAt, &i.PluginInstallationID, ); err != nil { return nil, err } items = append(items, i) } if err := rows.Err(); err != nil { return nil, err } return items, nil } const listAgentSkillsByWorkspace = `-- name: ListAgentSkillsByWorkspace :many SELECT ask.agent_id, s.id, s.name, s.description, ask.enabled FROM agent_skill ask JOIN skill s ON s.id = ask.skill_id WHERE s.workspace_id = $1 ORDER BY s.name ASC ` type ListAgentSkillsByWorkspaceRow struct { AgentID pgtype.UUID `json:"agent_id"` ID pgtype.UUID `json:"id"` Name string `json:"name"` Description string `json:"description"` Enabled bool `json:"enabled"` } func (q *Queries) ListAgentSkillsByWorkspace(ctx context.Context, workspaceID pgtype.UUID) ([]ListAgentSkillsByWorkspaceRow, error) { rows, err := q.db.Query(ctx, listAgentSkillsByWorkspace, workspaceID) if err != nil { return nil, err } defer rows.Close() items := []ListAgentSkillsByWorkspaceRow{} for rows.Next() { var i ListAgentSkillsByWorkspaceRow if err := rows.Scan( &i.AgentID, &i.ID, &i.Name, &i.Description, &i.Enabled, ); err != nil { return nil, err } items = append(items, i) } if err := rows.Err(); err != nil { return nil, err } return items, nil } const listSkillFileMetadata = `-- name: ListSkillFileMetadata :many SELECT id, skill_id, path, octet_length(content)::bigint AS size, encode(sha256(convert_to(content, 'UTF8')), 'hex') AS content_hash, created_at, updated_at FROM skill_file WHERE skill_id = $1 ORDER BY path ASC ` type ListSkillFileMetadataRow struct { ID pgtype.UUID `json:"id"` SkillID pgtype.UUID `json:"skill_id"` Path string `json:"path"` Size int64 `json:"size"` ContentHash string `json:"content_hash"` CreatedAt pgtype.Timestamptz `json:"created_at"` UpdatedAt pgtype.Timestamptz `json:"updated_at"` } // Metadata-only variant of ListSkillFiles: path, byte size and content hash // without the body. Same reason as ListSkillSummariesByWorkspace — a skill // whose supporting files total ~600KB cannot be listed at all when every row // carries its full content, and the one command that would show which file is // oversized was the command that timed out (GH multica-ai/multica#7498). // size/hash are computed in Postgres so the file bodies never leave it. // // convert_to(content, 'UTF8'), never content::bytea: the cast runs the bytea // INPUT parser over the text, so it reads backslash escapes instead of taking // the bytes. A file containing `\x41` would hash as the single byte `A`, and // one containing a bare backslash — a regex `\d+`, a Windows path, a LaTeX // snippet — fails outright with "invalid input syntax for type bytea", // turning an ordinary skill into a 500 on this endpoint. func (q *Queries) ListSkillFileMetadata(ctx context.Context, skillID pgtype.UUID) ([]ListSkillFileMetadataRow, error) { rows, err := q.db.Query(ctx, listSkillFileMetadata, skillID) if err != nil { return nil, err } defer rows.Close() items := []ListSkillFileMetadataRow{} for rows.Next() { var i ListSkillFileMetadataRow if err := rows.Scan( &i.ID, &i.SkillID, &i.Path, &i.Size, &i.ContentHash, &i.CreatedAt, &i.UpdatedAt, ); err != nil { return nil, err } items = append(items, i) } if err := rows.Err(); err != nil { return nil, err } return items, nil } const listSkillFiles = `-- name: ListSkillFiles :many SELECT id, skill_id, path, content, created_at, updated_at FROM skill_file WHERE skill_id = $1 ORDER BY path ASC ` // Skill File CRUD func (q *Queries) ListSkillFiles(ctx context.Context, skillID pgtype.UUID) ([]SkillFile, error) { rows, err := q.db.Query(ctx, listSkillFiles, skillID) if err != nil { return nil, err } defer rows.Close() items := []SkillFile{} for rows.Next() { var i SkillFile if err := rows.Scan( &i.ID, &i.SkillID, &i.Path, &i.Content, &i.CreatedAt, &i.UpdatedAt, ); err != nil { return nil, err } items = append(items, i) } if err := rows.Err(); err != nil { return nil, err } return items, nil } const listSkillFilesBySkillIDs = `-- name: ListSkillFilesBySkillIDs :many SELECT id, skill_id, path, content, created_at, updated_at FROM skill_file WHERE skill_id = ANY($1::uuid[]) ORDER BY skill_id, path ASC ` // Batch variant of ListSkillFiles: loads every file for a set of skills in one // round trip so LoadAgentSkills doesn't issue one query per skill on the // task-claim hot path. Ordered by skill_id so the caller can group in a single // linear pass. Like ListSkillFiles it returns full file bodies — callers that // only need metadata must use ListSkillFileMetadata instead. Uses // idx_skill_file_skill. func (q *Queries) ListSkillFilesBySkillIDs(ctx context.Context, skillIds []pgtype.UUID) ([]SkillFile, error) { rows, err := q.db.Query(ctx, listSkillFilesBySkillIDs, skillIds) if err != nil { return nil, err } defer rows.Close() items := []SkillFile{} for rows.Next() { var i SkillFile if err := rows.Scan( &i.ID, &i.SkillID, &i.Path, &i.Content, &i.CreatedAt, &i.UpdatedAt, ); err != nil { return nil, err } items = append(items, i) } if err := rows.Err(); err != nil { return nil, err } return items, nil } const listSkillSummariesByWorkspace = `-- name: ListSkillSummariesByWorkspace :many SELECT id, workspace_id, name, description, config, created_by, created_at, updated_at FROM skill WHERE workspace_id = $1 ORDER BY name ASC ` type ListSkillSummariesByWorkspaceRow struct { ID pgtype.UUID `json:"id"` WorkspaceID pgtype.UUID `json:"workspace_id"` Name string `json:"name"` Description string `json:"description"` Config []byte `json:"config"` CreatedBy pgtype.UUID `json:"created_by"` CreatedAt pgtype.Timestamptz `json:"created_at"` UpdatedAt pgtype.Timestamptz `json:"updated_at"` } // Same as ListSkillsByWorkspace but omits the SKILL.md `content` column. Used // by list endpoints (CLI table, web list page) where the body is never read; // shipping it everywhere blew up payload size on workspaces with many skills // and caused 15s CLI timeouts from high-latency regions (GH multica-ai/multica#2174). func (q *Queries) ListSkillSummariesByWorkspace(ctx context.Context, workspaceID pgtype.UUID) ([]ListSkillSummariesByWorkspaceRow, error) { rows, err := q.db.Query(ctx, listSkillSummariesByWorkspace, workspaceID) if err != nil { return nil, err } defer rows.Close() items := []ListSkillSummariesByWorkspaceRow{} for rows.Next() { var i ListSkillSummariesByWorkspaceRow if err := rows.Scan( &i.ID, &i.WorkspaceID, &i.Name, &i.Description, &i.Config, &i.CreatedBy, &i.CreatedAt, &i.UpdatedAt, ); err != nil { return nil, err } items = append(items, i) } if err := rows.Err(); err != nil { return nil, err } return items, nil } const listSkillsByWorkspace = `-- name: ListSkillsByWorkspace :many SELECT id, workspace_id, name, description, content, config, created_by, created_at, updated_at, plugin_installation_id FROM skill WHERE workspace_id = $1 ORDER BY name ASC ` // Skill CRUD func (q *Queries) ListSkillsByWorkspace(ctx context.Context, workspaceID pgtype.UUID) ([]Skill, error) { rows, err := q.db.Query(ctx, listSkillsByWorkspace, workspaceID) if err != nil { return nil, err } defer rows.Close() items := []Skill{} for rows.Next() { var i Skill if err := rows.Scan( &i.ID, &i.WorkspaceID, &i.Name, &i.Description, &i.Content, &i.Config, &i.CreatedBy, &i.CreatedAt, &i.UpdatedAt, &i.PluginInstallationID, ); err != nil { return nil, err } items = append(items, i) } if err := rows.Err(); err != nil { return nil, err } return items, nil } const removeAgentSkill = `-- name: RemoveAgentSkill :exec DELETE FROM agent_skill WHERE agent_id = $1 AND skill_id = $2 ` type RemoveAgentSkillParams struct { AgentID pgtype.UUID `json:"agent_id"` SkillID pgtype.UUID `json:"skill_id"` } func (q *Queries) RemoveAgentSkill(ctx context.Context, arg RemoveAgentSkillParams) error { _, err := q.db.Exec(ctx, removeAgentSkill, arg.AgentID, arg.SkillID) return err } const removeAllAgentSkills = `-- name: RemoveAllAgentSkills :exec DELETE FROM agent_skill WHERE agent_id = $1 ` func (q *Queries) RemoveAllAgentSkills(ctx context.Context, agentID pgtype.UUID) error { _, err := q.db.Exec(ctx, removeAllAgentSkills, agentID) return err } const setAgentSkillEnabled = `-- name: SetAgentSkillEnabled :execrows UPDATE agent_skill SET enabled = $3 WHERE agent_id = $1 AND skill_id = $2 ` type SetAgentSkillEnabledParams struct { AgentID pgtype.UUID `json:"agent_id"` SkillID pgtype.UUID `json:"skill_id"` Enabled bool `json:"enabled"` } func (q *Queries) SetAgentSkillEnabled(ctx context.Context, arg SetAgentSkillEnabledParams) (int64, error) { result, err := q.db.Exec(ctx, setAgentSkillEnabled, arg.AgentID, arg.SkillID, arg.Enabled) if err != nil { return 0, err } return result.RowsAffected(), nil } const updateSkill = `-- name: UpdateSkill :one UPDATE skill SET name = COALESCE($2, name), description = COALESCE($3, description), content = COALESCE($4, content), config = COALESCE($5, config), updated_at = now() WHERE id = $1 RETURNING id, workspace_id, name, description, content, config, created_by, created_at, updated_at, plugin_installation_id ` type UpdateSkillParams struct { ID pgtype.UUID `json:"id"` Name pgtype.Text `json:"name"` Description pgtype.Text `json:"description"` Content pgtype.Text `json:"content"` Config []byte `json:"config"` } func (q *Queries) UpdateSkill(ctx context.Context, arg UpdateSkillParams) (Skill, error) { row := q.db.QueryRow(ctx, updateSkill, arg.ID, arg.Name, arg.Description, arg.Content, arg.Config, ) var i Skill err := row.Scan( &i.ID, &i.WorkspaceID, &i.Name, &i.Description, &i.Content, &i.Config, &i.CreatedBy, &i.CreatedAt, &i.UpdatedAt, &i.PluginInstallationID, ) return i, err } const upsertSkillFile = `-- name: UpsertSkillFile :one INSERT INTO skill_file (skill_id, path, content) VALUES ($1, $2, $3) ON CONFLICT (skill_id, path) DO UPDATE SET content = EXCLUDED.content, updated_at = now() RETURNING id, skill_id, path, content, created_at, updated_at ` type UpsertSkillFileParams struct { SkillID pgtype.UUID `json:"skill_id"` Path string `json:"path"` Content string `json:"content"` } func (q *Queries) UpsertSkillFile(ctx context.Context, arg UpsertSkillFileParams) (SkillFile, error) { row := q.db.QueryRow(ctx, upsertSkillFile, arg.SkillID, arg.Path, arg.Content) var i SkillFile err := row.Scan( &i.ID, &i.SkillID, &i.Path, &i.Content, &i.CreatedAt, &i.UpdatedAt, ) return i, err }