Fix LLM Wiki package and migration validation (#6010)
## Thinking Path > - Paperclip orchestrates AI agents for zero-human companies. > - Plugins extend the control plane with optional capabilities such as LLM Wiki. > - LLM Wiki needs its package assets and plugin-owned database migrations to work when installed from the packaged plugin. > - The bundled spaces migration used validation-hostile dynamic SQL, and the packaged plugin could omit non-dist runtime assets. > - This pull request makes the LLM Wiki package include its required assets and cuts the spaces migration over to explicit, idempotent SQL that passes the production plugin database validator. > - The benefit is a simpler plugin install path that validates and applies the bundled LLM Wiki migrations without adding plugin-specific legacy handling to Paperclip core. ## What Changed - Added the LLM Wiki package asset allowlist so agents, migrations, skills, templates, dist output, and README are included when packaged. - Renamed the bootstrap `.gitignore` template to `gitignore.template` and updated the runtime lookup so package tooling does not drop the hidden template file. - Relaxed plugin migration validation to allow namespace-scoped `INSERT`/`UPDATE` backfills and `CREATE INDEX` statements while continuing to reject destructive or cross-namespace SQL. - Replaced the LLM Wiki spaces migration's dynamic constraint-drop DO block with explicit `DROP CONSTRAINT IF EXISTS` statements. - Replaced fragile regex-source dispatch in SQL reference extraction with explicit capture-group descriptors. - Added regression coverage that applies the bundled LLM Wiki migrations through the production validator and checks the expected constraints. ## Verification - `pnpm exec vitest run --project @paperclipai/server server/src/__tests__/plugin-database.test.ts --pool=forks --poolOptions.forks.isolate=true` - `pnpm --filter @paperclipai/plugin-llm-wiki build` - `git diff --check` - Confirmed `pnpm-lock.yaml` is not included in the branch diff. ## Risks - Low migration risk for current users: LLM Wiki spaces are new, so this intentionally cuts over the plugin migration instead of adding legacy handling in core. - Validator behavior is broader than before, but still requires fully qualified plugin namespace targets, blocks deletes/destructive DDL, and keeps public table access read-only and allowlisted. > Checked [`ROADMAP.md`](ROADMAP.md); this is a targeted plugin packaging/migration fix and does not duplicate planned core feature work. See `CONTRIBUTING.md`. ## Model Used - OpenAI Codex, GPT-5 based coding agent, tool-enabled local repo access, reasoning mode managed by the Paperclip/Codex runtime. Exact context window was not surfaced in this session. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] If this change affects the UI, I have included before/after screenshots - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing>
This commit is contained in:
@@ -140,37 +140,14 @@ ALTER TABLE plugin_llm_wiki_8f50da974f.paperclip_distillation_runs ALTER COLUMN
|
||||
ALTER TABLE plugin_llm_wiki_8f50da974f.paperclip_source_snapshots ALTER COLUMN space_id SET NOT NULL;
|
||||
ALTER TABLE plugin_llm_wiki_8f50da974f.paperclip_page_bindings ALTER COLUMN space_id SET NOT NULL;
|
||||
|
||||
DO $$
|
||||
DECLARE
|
||||
target record;
|
||||
constraint_name text;
|
||||
BEGIN
|
||||
FOR target IN
|
||||
SELECT * FROM (VALUES
|
||||
('wiki_pages', ARRAY['company_id', 'wiki_id', 'path']::text[]),
|
||||
('paperclip_distillation_cursors', ARRAY['company_id', 'wiki_id', 'source_scope', 'scope_key', 'source_kind']::text[]),
|
||||
('paperclip_distillation_work_items', ARRAY['company_id', 'wiki_id', 'idempotency_key']::text[]),
|
||||
('paperclip_page_bindings', ARRAY['company_id', 'wiki_id', 'page_path']::text[])
|
||||
) AS targets(table_name, column_names)
|
||||
LOOP
|
||||
FOR constraint_name IN
|
||||
SELECT c.conname
|
||||
FROM pg_constraint c
|
||||
JOIN pg_class t ON t.oid = c.conrelid
|
||||
JOIN pg_namespace n ON n.oid = t.relnamespace
|
||||
WHERE n.nspname = 'plugin_llm_wiki_8f50da974f'
|
||||
AND t.relname = target.table_name
|
||||
AND c.contype = 'u'
|
||||
AND (
|
||||
SELECT array_agg(a.attname ORDER BY constraint_columns.ordinality)::text[]
|
||||
FROM unnest(c.conkey) WITH ORDINALITY AS constraint_columns(attnum, ordinality)
|
||||
JOIN pg_attribute a ON a.attrelid = c.conrelid AND a.attnum = constraint_columns.attnum
|
||||
) = target.column_names
|
||||
LOOP
|
||||
EXECUTE format('ALTER TABLE %I.%I DROP CONSTRAINT %I', 'plugin_llm_wiki_8f50da974f', target.table_name, constraint_name);
|
||||
END LOOP;
|
||||
END LOOP;
|
||||
END $$;
|
||||
ALTER TABLE plugin_llm_wiki_8f50da974f.wiki_pages
|
||||
DROP CONSTRAINT IF EXISTS wiki_pages_company_id_wiki_id_path_key;
|
||||
ALTER TABLE plugin_llm_wiki_8f50da974f.paperclip_distillation_cursors
|
||||
DROP CONSTRAINT IF EXISTS paperclip_distillation_cursor_company_id_wiki_id_source_sco_key;
|
||||
ALTER TABLE plugin_llm_wiki_8f50da974f.paperclip_distillation_work_items
|
||||
DROP CONSTRAINT IF EXISTS paperclip_distillation_work_i_company_id_wiki_id_idempotenc_key;
|
||||
ALTER TABLE plugin_llm_wiki_8f50da974f.paperclip_page_bindings
|
||||
DROP CONSTRAINT IF EXISTS paperclip_page_bindings_company_id_wiki_id_page_path_key;
|
||||
|
||||
ALTER TABLE plugin_llm_wiki_8f50da974f.wiki_pages
|
||||
DROP CONSTRAINT IF EXISTS wiki_pages_company_wiki_space_path_key;
|
||||
|
||||
@@ -4,6 +4,14 @@
|
||||
"type": "module",
|
||||
"private": true,
|
||||
"description": "Local-file LLM Wiki plugin for source ingestion, wiki browsing, query, lint, and maintenance workflows.",
|
||||
"files": [
|
||||
"agents",
|
||||
"dist",
|
||||
"migrations",
|
||||
"skills",
|
||||
"templates",
|
||||
"README.md"
|
||||
],
|
||||
"scripts": {
|
||||
"prebuild": "pnpm --filter @paperclipai/plugin-sdk ensure-build-deps",
|
||||
"build": "node ./esbuild.config.mjs",
|
||||
|
||||
@@ -46,7 +46,7 @@ export const DEFAULT_AGENT_INSTRUCTIONS = DEFAULT_AGENT_INSTRUCTION_FILES["AGENT
|
||||
export const DEFAULT_IDEA = templateFile("IDEA.md");
|
||||
export const DEFAULT_INDEX = templateFile("wiki/index.md");
|
||||
export const DEFAULT_LOG = templateFile("wiki/log.md");
|
||||
export const DEFAULT_GITIGNORE = templateFile(".gitignore");
|
||||
export const DEFAULT_GITIGNORE = templateFile("gitignore.template");
|
||||
|
||||
export const QUERY_PROMPT = `Answer from the LLM Wiki using the installed wiki-query skill.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user