feat(kc): KindredDocument class — silo/ directory parse, expose, promote, and demote #45
Reference in New Issue
Block a user
Delete Branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Summary
Implement
KindredDocument, a Python wrapper class that manages thesilo/directory contents across the document lifecycle. This is Layer 2 of the KC Specification — it sits between the C++ format registration (Layer 1) and the Silo workbench integration (Layer 3).Currently,
kc_format.pyhandles ZIP round-trip preservation and manifest auto-creation but does not parse, expose, or managesilo/content.KindredDocumentfills this gap.Background
kc_format.pytoday:silo/ZIP entries before save and reinjects them after savesilo/manifest.jsonon first savemodified_attimestamp on each savesilo/content on open.fcstd→.kc) or demotion (.kc→.fcstd)KindredDocumentwill:silo/entries when a.kcis openedkc_format.py(ZIP I/O) and the viewport system (tree objects, viewer widgets)Scope
New file:
src/Mod/Create/kindred_document.pyBehavior by operation
.kcsilo/entries from ZIP. Expose as structured data. Signal tree builder to create Silo objects..fcstdsilo/directory.KindredDocumentis inactive..kcsilo/entries. Coordinate withkc_format.pyviapre_reinject..fcstd.fcstd→.kcsilo/manifest.jsonwith new UUID. Optionally prompt for schema field selection if connected to Silo.Behavior by
silo/entrymanifest.jsonmodified_atandrevision_hashmetadata.jsonhistory.jsonapprovals.jsondependencies.jsonmacros/jobs/thumbnails/inspection/Integration with
kc_format.pyKindredDocumentregisters apre_reinjectcallback (added by Phase 1, issue #37) that receives thesilo/cache dict before ZIP write. It serializes current state from all Silo tree objects into the cache, ensuring edits made in viewer widgets are persisted.Integration with
silo_document.pySiloDocumentObserver(Phase 1) handles the signal hooks (slotCreatedDocument, etc.).KindredDocumentis instantiated by the observer and attached to each.kcdocument. The observer delegates lifecycle events toKindredDocument.Key design decisions
One
KindredDocumentper open.kcdocument: Stored as a module-level dict keyed bydoc.Name. Cleaned up onslotDeletedDocument.Lazy parsing:
silo/entries are parsed on first access, not all at once on open. This avoids blocking the UI for large.kcfiles with many entries.Schema validation on open: If
metadata.jsonreferences a schema and Silo is connected, fetch the schema descriptor for field validation. If offline, skip validation and display raw values.Promotion dialog: When promoting
.fcstd→.kc, show a dialog that allows the user to:GET /api/schemasif connected)Files to modify
src/Mod/Create/kindred_document.pyKindredDocumentclasssrc/Mod/Create/silo_document.pyKindredDocumentfor.kcdocuments, delegate lifecycle eventssrc/Mod/Create/InitGui.pysrc/Mod/Create/CMakeLists.txtkindred_document.pyto install listAcceptance criteria
.kcwith populatedsilo/metadata.jsonexposes schema fields to the viewer system.kcwith allsilo/entry types correctly parses each one.fcstddoes not create aKindredDocumentinstance.kcpersists metadata changes from viewer edits across close/reopen cycles.fcstdto.kcassigns a UUID and createssilo/manifest.jsonKindredDocumentis cleaned up when a document is closed.kc→ edit metadata via viewer → save → reopen → edits persistedDependencies
SiloDocumentObserverandpre_reinjecthook.kcdialog registration)References
docs/KC_SPECIFICATION.md§6 Layer 2 (Silo Metadata Layer)src/Mod/Create/kc_format.py— existing ZIP round-trip logic