Conversation
compatibility.verified was "13.351" while minimum was "14.359" - verified must never be lower than minimum. Looks like a v13/v14 field cross-contamination similar to the incident that caused the original v14 rollback. Reset verified to match minimum until tested against a newer 14.x build.
Previously only the quest title round-tripped to the API; every other field (giver, category, status, success/failure/next-action/resolution) was display-only after first import, objectives were local-only, and Quests sat outside the shared linking system entirely. - Info tab is now a structured edit form instead of a stubbed ProseMirror body (Quest has no generic `description` field in the API); drop the hack that stuffed successDefinition/nextAction into page content on import. - _commitEdits sends the full updateQuest payload, not just questName. - Objectives (add/remove/edit text+status) sync to the API instead of being local-flag-only. - Quest relationships persist via relatedEntityRefs on the quest itself (updateQuest), since the API's link system has no ENTITY_CONFIG entry for Quest in either direction. Links tab now renders real, clickable, unlinkable cards backed by entity IDs instead of static name chips. - Character/Item/Location/Faction sheets get a read-only "Quests" tab (client-side filtered from listQuests(), since there's no reverse lookup endpoint) so relationships are visible from both sides. - reconcile-service now includes quests/journals in the ongoing sync pass, not just first import. - Documented Quest/Journal/Links shapes in the Cursor API rules doc, which previously covered every other entity but not these. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Historically users couldn't import existing Foundry Actor/Item images
because they're stored locally and the module had no way to send image
bytes to the API. Confirmed the API's actual upload shape: a 3-step
presigned-URL flow (init -> PUT bytes directly to R2 -> complete), not
a raw multipart POST. 4.5MB cap and content-sniffing are server-enforced.
- archivist-api.js: initImageUpload/uploadImageBytes/completeImageUpload
plus a uploadEntityImage convenience wrapper running all three steps.
- Character/Item/Location/Faction sheets get an "Upload local image"
header button (GM-only) that reads the linked Actor/Item/Scene's (or
the journal's own) local img via fetch() and pushes it to Archivist.
Not available for Quest — the API has no image support for that type.
- archivist-api.js: added updateLink (PATCH) alongside the existing
createLink/deleteLink so a link's alias can be corrected in place
instead of delete+recreate, once a UI flow needs it.
Other endpoints surveyed but intentionally left for a future pass to
keep this change bounded: unified /campaigns/{id}/search, the
lightweight /entities picker endpoint, session transcript/handout ->
Journal auto-generation, the recordings/transcription pipeline, and
journal-folder CRUD (create/rename/delete).
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Confirmed zero references anywhere in the repo (grep across .js/.json). Stray backup file, not part of the build. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Project Descriptions is documented as "Append an Archivist section to the most likely description field," but projectDescription() only appended for HTML-flagged slots (via mergeArchivistSection). For the one plain-text slot in the registry (dnd5e/pf2e Actor system.details.notes, adapter-registry.js html:false) — which becomes the top candidate for actor subtypes lacking a biography field, e.g. dnd5e's vehicle/group types — the code did stripHtml(archivistHtml) with no reference to the field's existing content at all, silently replacing whatever was there. This matches user reports of losing existing descriptions. Added mergeArchivistPlainSection (merge.js), which does for plain-text fields what mergeArchivistSection already did for HTML ones: wrap the Archivist content in a recognizable marker, append it if none exists yet, and replace only that marked block on future syncs — never touching the rest of the field's content. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Quests were already being auto-imported exactly like Factions/Recaps — _importArchivistMissing() pulls them in unconditionally, no reconcile/ selection step, and the count was already being computed (count.imp.quests / plan.importFromArchivist.quests). They just never made it into the summaryRows array the Step 6 table renders from, so the count was invisible before clicking "Start Sync." Added a Quests row identical in shape to the Recaps row, and updated Step 4's helper note (which named Factions/Recaps as auto-imported) to mention Quests too. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Two real bugs, both regressions from the Quests/image-upload work:
1. The upload-local-image button reused .archivist-edit-toggle's exact
`position: absolute; top: 8px; right: 8px` slot with no offset, so
it rendered directly on top of the edit-mode toggle — completely
covering it. That's why editing a Faction (or any Character/Item/
Location) sheet looked impossible: the button was there, just
unclickable underneath the newer one. Added a distinguishing
.archivist-upload-toggle class with `right: 48px` so they sit side
by side.
2. _onRender fired _renderLinkedGrids()/_renderActorItemCards()/
_renderRelatedQuests() without awaiting them, all async (dynamic
import + DOM work). Verified against Foundry's own core source
(client/applications/api/application.mjs): _render() does
`await this._doEvent(this._onRender, ...)`, but since our _onRender
wasn't declared async, that await resolved as soon as the
synchronous body returned — before grid population finished. Opening
a sheet by clicking a card in another custom sheet chains
.render({force:true}).then(bringToFront) right after that early
resolution, so the window could appear with cards populated but tab
counts (the "(N)" suffix, set later by the same population pass)
never applied — a real, reproducible gap, not just a cosmetic flash.
Made _onRender (base class, plus the Location and Quest overrides
that call super._onRender) async and properly awaited so Foundry's
pipeline doesn't consider the render complete until population
actually finishes.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…l work A collaborator independently built the same quest/journal feature set on his fork (upstream/quest-journal-review-fixes, from the same 40d439f base). His module.json/compatibility changes and the ask-chat-sidebar-tab.js deletion are NOT ported — that branch reintroduces the exact incident this whole effort started from (a v14-only build with compat.minimum low enough for v13 clients to install, missing the Sidebar.TABS registration v13 actually needs). But several of his bug fixes are real, verified independently against this branch's actual call sites, and are ported here: - sync-dialog.js: journal content was being dropped entirely on import/sync (read row.description/row.summary but never row.content, which is where Journal's actual content lives) — the most serious bug found. Also: shift+click range-select was getting flipped back by the row-level click handler (missing stopPropagation); journal names were interpolated unescaped into the delete-confirmation dialog's HTML; no folder fallback for journals/quests on worlds that predate this feature, landing them in the world root. Wholesale-replaced with the fixed version, then re-added this branch's own relatedEntityRefs hydration (needed by the richer quest-linking Links tab) which his simpler version doesn't populate. - world-setup-dialog.js: added _updateSyncStatusUI() (direct progress-bar DOM update) to the six "always imported in full" loops (characters, items, locations, factions, journals, quests), replacing a full await this.render() per entity — a real perf cost on large imports. - archivist-sync.js: the realtime page-content-edit hook was PATCHing the quest's unchanged name back to the API on every content keystroke commit; quest content isn't a synced field and renames are already handled by a separate title-sync hook, so this was pure waste. Now a no-op return. - archivist-api.js: _normalizeQuestPayload rewritten from a blocklist (rename+delete known keys, pass everything else through) to a strict whitelist, matching QuestCreate/QuestUpdate's extra="forbid" schema. Verified no current call site was actually vulnerable (all send narrow literal payloads), but the whitelist is a strictly safer contract for any future caller — verified functionally: read-only fields (questGiverId, progressLogEntries, first/lastSession) are dropped, empty-text objectives are dropped (API requires min_length=1), relatedEntityRefs' nested keys stay camelCase as the backend's alias_generator expects. Also fixed the keepalive guard: Chromium rejects keepalive fetches over ~64KB, so it's now conditional on body size instead of unconditional for all writes. - merge.js: stripHtml no longer calls foundry.utils.TextEditor.stripHTML, which doesn't exist in either v13 or v14 core (verified against the actual installed Foundry app) — always fell through to the manual DOM-based strip anyway, just via a dead branch first. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Co-Authored-By: camrun01 <cameron.b.llewellyn@gmail.com>
Adopts camrun91's approach: QuestPageSheetV2._localize(key) tries game.i18n.localize() and returns null (not the raw key) on a miss or when i18n isn't ready yet, so callers can chain `|| fallback` cleanly. statusLabel/categoryLabel now try ARCHIVIST_SYNC.quest.status.*/ category.* (already present in lang/en.json from the earlier merge of his branch's new keys) before falling back to the hardcoded English strings that were the only source before. Not in scope here: the edit-mode <select> option text in quest.hbs (questCategory/status dropdowns) — those don't exist on his branch at all (it kept the free-text Info tab instead of the structured form), so there's nothing of his to adopt for them; they're still hardcoded English, same as before this change. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Co-Authored-By: camrun01 <cameron.b.llewellyn@gmail.com>
Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
…n API rules - Add _invalidateQuestsCache() and call from _commitEdits (quest), _commitQuestLinks, and _syncObjectives so related-quest tabs refresh immediately after linking or editing - Correct 40-archivist-api.mdc to document that _normalizeQuestPayload emits snake_case on the wire while _normalizeQuestResponse ingests camelCase internally Co-authored-by: Cameron Llewellyn <cameron.b.llewellyn@gmail.com>
Read form objectives before building the commit payload so _commitEdits sends a single atomic PATCH covering all editable quest fields, avoiding local/API divergence when per-field objective sync calls fail silently. Co-authored-by: Cameron Llewellyn <cameron.b.llewellyn@gmail.com>
Finish Quests feature, add image upload + link PATCH, fold in review fixes from #46
Owner
Author
|
these were pulled into another PR |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
Type of Change
Checklist
npm run lint:fixand fixed any remaining errorsTesting
Foundry VTT Version:
Game System:
Screenshots (if applicable)
Related Issues
Closes #