Commit graph

114 commits

Author SHA1 Message Date
Titus
74637e3754 3.0.0 2026-07-17 10:36:45 +02:00
Titus
1df5241c7a README sweep: PluginFiles accurate + Upload guard wording matches audit fix
- PluginFiles is now just a README + settings note (templates retired), not
  'managed automatically'.
- Upload World: reworded the link-preservation line to describe the actual
  omit-whole-field-on-unresolved behavior (the audit fix), not the vague
  'skipped'.
2026-07-17 10:09:21 +02:00
Titus
72b26e3304 audit fixes: upload link-loss guard + migration wikilinks + id-match
Cold pre-release audit (release-auditor, verified against source) found one
real regression + polish:

#1 DATA-LOSS (regression vs 2.3.0): the bulk upload path (Export/Upload World)
built a full-field PATCH from a SHORTENED link list when a [[Name]] didn't
resolve locally, stripping the server's copy of the dropped link. The span
path guards this (omit-field-on-unresolved); the frontmatter path lost it.
Fix: frontmatterToPayloadFields gains omitFieldOnUnresolved; readElement sets
it so any field with an unresolvable link is OMITTED (server value wins), not
shortened. Self-contained detection (input-count vs resolved-count) — no
reliance on a caller-supplied tracking array (a test caught that fragility).
4 new tests pin it.

#2 polish: migration now renders link fields as [[Name]] wikilinks (was raw
ids until next download) — scrapeIdToName resolver threaded into
apiDataToFrontmatter.

#3 polish: DownloadWorldCommand.findElementByIdInCategory matches frontmatter
 first (was span-only), so re-download rename detection works on migrated
notes.

#4 (NameChanger self-write during download) left as documented no-op traffic.

Gate: tsc clean, build clean, 64/64 tests.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-17 09:52:09 +02:00
Titus
06697bddbb Link picker: refresh Properties view after write (no more go-away-and-back)
processFrontMatter updates the file but the open editor's Properties panel
lags until metadataCache re-indexes, so a just-linked/unlinked value didn't
show until you left and returned. After a link write, re-set the active view's
state to force a clean properties re-render (best-effort; the write already
succeeded regardless). Captain-verified live.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-17 09:39:48 +02:00
Titus
4a0ec0f395 Link picker: toggle list (add AND remove) + search box + shows existing
The picker was add-only — calling it 'Edit' but never letting you unlink was
the real wrong. Reworked ElementSelectionModal into a toggle list: every
element of the type shown, already-linked ones pre-checked, click toggles
link/unlink, checked-first ordering, search box for long lists. Multi-link
confirms a set on Done; single-link is radio-style (pick sets + closes) with a
Clear-link option to unset. NoteLinker computes current links (resolving
[[Name]] via the path-aware resolver) to pre-check, and writeLink now REPLACES
the field with exactly the chosen set instead of merge-only.

Gate: tsc clean, build clean, 60/60 tests.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-17 09:27:59 +02:00
Titus
7d36a3f137 Link Elements writes [[wikilinks]] + modal UX (was writing raw ids)
THE bug: NoteLinker.writeLink wrote raw UUIDs into link fields — the one
write path never updated for the 3.0.0 readability change, so linking via
the command produced unreadable uuid fields. Now writes [[Name]] wikilinks
(sanitized to match the on-disk basename), merging by name AND id so an
existing raw-id or wikilink entry isn't duplicated — old raw-id links
self-heal to wikilinks on next edit. Merge logic unit-verified (add / re-add /
raw-id-upgrade / colon-name).

Modal UX (Captain's asks): field picker shows each field's current link count
(empty vs filled), sorts single links first then empty-before-filled, dims
already-filled fields, Add/Edit button label. README notes native Property
autocomplete as a second linking path.

Gate: tsc clean, build clean, 60/60 tests + merge unit-check.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-17 09:21:05 +02:00
Titus
6c04bf692c 3.0.0 batch: template-free everywhere, read-key pinless download, docs
- Template fetch retired: Create/Download/Paste no longer fetch or write the
  legacy PluginFiles/Templates + Handlebars sets (nothing reads them — every
  note write is frontmatter via writeElement). includeLegacyTemplates defaults
  false; the two Create* template commands kept as a reversible margin.
- Read-only keys need no PIN: WorldDownloadModal detects ow_r_ / demo keys and
  greys out the PIN field; validation accepts a blank PIN and sends "". Write
  keys and private-world write keys still require the 4-digit PIN (unit-checked:
  read keys skip, write keys don't — no auth hole). pin type: number -> string.
- Docs: README read-key note + all commands current; release notes reversioned
  2.4.0 -> 3.0.0 (the frontmatter era: format change + folder bridge + span
  retirement = a major).

Gate: tsc clean, build clean, 60/60 tests + pinless-detection unit check.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-17 09:12:53 +02:00
Titus
ee3204cc75 PasteWorld writes frontmatter (was still emitting span-format)
PasteWorld was the last command still writing the legacy <span> format via
vault Handlebars templates — a broken command on a 2.4.0 vault, not a
deferred feature. Swapped its element-write path for writeElement (the same
frontmatter writer Download uses): builds an id->name map from the pasted
payload for [[Name]] wikilinks, reuses existing notes by embedded id (now
matching frontmatter id: too), preserves extension fields. World.md write
unchanged. Copy->Paste round-trips through one writer now.

Gate: tsc clean, build clean, 60/60 tests. (Write path is Obsidian-runtime,
identical contract to the Captain-smoke-verified Download path.)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-17 08:45:41 +02:00
Titus
7ed0c1cfca 2.4.0 prep: ValidateWorld skips frontmatter, README + release notes current
- ValidateWorld: skip frontmatter notes instead of showing false 'missing
  Id/Name' errors on migrated worlds (the span linter can't judge them; a
  frontmatter-aware validator is future work). The user-facing lie is the
  actual harm; this removes it without a full rewrite.
- README: frontmatter format + clickable [[wikilink]] fields, the Migrate
  command + note-format/migration section, folder Export/Import commands,
  folder-bridge in the ecosystem section. Voice preserved (Captain's), facts
  brought to 2.4.0.
- 2.4.0 release-notes draft (the GitHub release body + Captain's gate).

Gate: tsc clean, build clean, 60/60 tests.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-17 08:32:25 +02:00
Titus
10951cbacf gate fix: writeElement filename uses canonical sanitizeFileName
The download id->name map sanitizes wikilink targets with WorldService's
sanitizeFileName (strips control chars + trailing dot/space, 'unnamed'
fallback), but writeElement named the actual file with a WEAKER regex
(colon/slash class only). A name with a trailing dot or control char would
name the file one way and the [[link]] another -> dangling link. Both now
use sanitizeFileName, so the wikilink always matches the on-disk basename.

Also files the download-resolver brief.

Gate: tsc clean, build clean, npm test 60/60 (orchestrator hands).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-16 22:50:10 +02:00
Titus
c8178763b6 S9: pin colon-name round-trip -- sanitized basename wraps to a clickable [[link]]
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-16 22:47:52 +02:00
Titus
c5e08180f0 S9: resolve link names at download time from payload, not the cache
Link fields rendered as raw UUIDs after a real download: writeElement
resolved id->name via metadataCache, which is cold for freshly-written
sibling notes mid-bulk-write, so nearly every link stayed a bare id.

Fix (restores the old linkifyContent/buildVaultNameIndex approach for the
frontmatter format):
- WriteElementOpts gains an idToName map; when present writeElement uses it
  instead of the cache-scanning buildIdToNameResolver (absent = back-compat).
- DownloadWorldCommand builds ONE complete id->basename map before the write
  loop: seeded from the in-memory payload (freshest names) with a raw-disk
  fallback (parseRawFrontmatterScalars, NO metadataCache) for ids outside an
  incremental pull's changed set. Names pass through sanitizeFileName so the
  written [[Name]] resolves by filename. Unknown id -> raw id (never dropped).
- parseRawFrontmatterScalars added to element-transform (pure, dep-free) +
  unit tests; plus a download-style injected-map render test. 59/59 green.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-16 22:46:31 +02:00
Titus
41f8ab1839 docs: file the readability-bout brief
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-16 22:24:52 +02:00
Titus
52bf5af3df S9: readable [[Name]] wikilinks + lean note layout
Link fields now render as clickable [[Name]] wikilinks instead of raw
UUIDs (R1), empty fields are omitted (R3), and OW-internal fields (id,
image_url) sink to the bottom of the Properties panel (R4).

- element-transform.ts (pure): apiDataToFrontmatter takes an optional
  id->name resolver (raw-id fallback keeps dangling/cross-world links);
  frontmatterToPayloadFields takes an optional name->id resolver + an
  unresolved sink (wikilinks resolve to ids, bare uuids pass through,
  unresolvable reported not guessed). Empty-omit + name-first/id-last
  ordering. Extension fields never wikilinked, never empty-omitted.
- element-file.ts (Obsidian): buildIdToNameResolver (write) +
  path-aware buildWikilinkResolver via getFirstLinkpathDest (read);
  writeElement rebuilds owned keys in R4 order; readElement logs any
  dropped unresolved links.
- 13 new pure tests (write/read/empty-omit/order/round-trip/extension).

Migrate + Export consume the resolver-optional functions unchanged.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-16 22:21:52 +02:00
Titus
491b05d232 smoke: test both export destinations + note which dialog path fires
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-16 17:41:54 +02:00
Titus
6887dbe8f4 docs: file the export-picker brief (was untracked)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-16 17:41:17 +02:00
Titus
8e24a83a93 S9: export destination picker -- write straight into Atlas root
Add a destination choice to "Export as OnlyWorlds folder": keep the
vault-internal default (OW-folder-export/) and add "Choose a folder..."
that writes the conformant folder into any real OS directory -- point it
at the Atlas root for a one-step handoff.

- External sink uses node fs/promises + absolute paths (escapes the vault
  sandbox, verified); vault sink unchanged (vault API).
- Serialization shared via planFiles(); only the sink differs.
- Native picker reached by a guarded multi-path probe; falls back to a
  paste-absolute-path modal if no Electron dialog is reachable.
- Desktop-only: external option hidden on mobile.
- R3 safety: refuse if target exists or dest holds an open Atlas world
  (.atlas / lock). Pure refusal logic in export-plan.ts, unit-tested.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-16 17:39:27 +02:00
Titus
bdb1eff8d1 docs: core smoke checklist + Atlas-handoff design finding
CORE-SMOKE.md: the 10-min pass. Records what Skeld verified by execution
(migration correctness on Captain's real MessWorld run — 22/22, 0 residue;
extension-field round-trip incl. nested objects, both via the plugin's own
transform) vs the human-only pass (download/save/migrate/folder-bridge).

atlas-handoff-design.md: why the plugin can't auto-detect the Atlas root
(browser FS-Access sandbox, opaque IDB handles, no shared path — confirmed
against Atlas source in the Forge), and that a destination picker is the
chosen smoothing (executor building it).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-16 17:37:26 +02:00
Titus
1a988b9138 smoke fix: ignore the sync cursor when the vault holds no notes for the world
Captain's first smoke: Download World on a fresh vault wrote World.md and
nothing else, no errors. Cause: data.json outlives vault content — a stored
cursor at head means 'changes since' = zero, honestly written into an empty
vault. The watermark now sanity-checks against vault reality: no element
notes for the world -> cursor ignored, cold full pull.

Gate: tsc clean, build clean, npm test 34/34.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-16 15:15:51 +02:00
Titus
de0bf09005 keeper ruling: stable per-vault world identity for the folder bridge
Export minted a FRESH world id every run (faithful to folder.js, wrong for
this context: azgaar conversions ARE new worlds each time; a vault world is
persistent). Consequences: every re-export lands in Atlas as a brand-new
world, and re-importing a re-export trips the never-merge guard against the
same world's own earlier import.

Fix: shared vault/world-id-marker.ts (adapter-only dotfile I/O, documented) —
export reads-or-mints-and-persists the id; import records the imported
folder's id as before. Re-exports are now identity-stable.

Gate: tsc clean, build clean, npm test 34/34 (orchestrator hands).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-16 14:11:38 +02:00
Titus
4a09d8800a gate fix: world-id marker must use the adapter, not the vault API
Obsidian's vault index excludes dot-prefixed files: getAbstractFileByPath on
.ow-world-id returns null forever and vault.create refuses the path, so the
R5 never-merge-two-worlds guard was inert as written — a same-name world with
a different id would import and silently merge. Marker read/write now goes
through vault.adapter (raw fs, dotfile-capable); unindexed files emit no vault
events so the self-write mark is unnecessary there.

Gate: tsc clean, build clean, npm test 34/34 (orchestrator hands).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-16 14:07:02 +02:00
Titus
801cf64a44 Phase C: OnlyWorlds folder bridge (export/import commands)
Two additive commands making the plugin the folder format's fourth
implementation (after Atlas, Magelet, azgaar-converter):

- Export as OnlyWorlds folder: walk a world's notes -> conformant folder
  under OW-folder-export/ (vault-internal). world.json id+name, spatial
  bucketing, body type/local_updated_at/created_at stamp, <slug>--<tail>
  filenames. [[wikilink]] -> ow://type/uuid where names resolve.
- Import OnlyWorlds folder: read a world folder placed in the vault, mint
  frontmatter notes via Phase B's writeElement. ow:// -> [[wikilink]],
  skip-existing-id safety, abort on world-id mismatch, verbatim extension
  fields.

Pure serializers in vault/folder-format.ts (no Obsidian imports), 13 new
tests: conformance pins for all four Atlas-ingest facts + in-memory
round-trip (object equality on ids/links/extension keys/story). Phase B's
21 tests stay green. Smoke section G appended.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-16 14:03:07 +02:00
Titus
4b056022eb gate fixes: frontmatter elements keep their id through Upload/Copy
readElement returns id OUTSIDE .fields; the Phase B guards in Export and Copy
returned parsed.fields bare, so on a fully-migrated world Upload World would
silently skip EVERY element (the sweep's if-no-id-continue) while reporting
success, and Copy World would emit id-less JSON that breaks paste dedupe.
Both guards now return { id, ...fields }. Smoke step 17 strengthened to check
the uploaded count and spot-check ids in copied JSON, so this class stays dead
at the user layer too.

Gate: tsc clean, build clean, npm test 21/21 (orchestrator hands).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-16 13:54:47 +02:00
Titus
c11db83d57 R9: writer-minted migration fixtures + entity-decode fix
Mint authentic old-format span fixtures via the REAL writer (real handlebars lib
+ verbatim upstream templates + linkify helper + [[id]]->[[Name]] rewrite) rather
than hand-written strings, per the R9 addendum. test/span-writer.ts (minter, with
disclosure that template STRINGS are transcribed but the RENDER is genuine) +
test/migration-roundtrip.test.ts (5 cases: Character multi-links, Narrative
body->story, apostrophe/HTML-entity, comma-in-linked-name, extension-field
round-trip).

The writer-minted apostrophe fixture caught a REAL bug hand-written fixtures
missed: the migration path did NOT decode HTML entities, so a pre-2.2.2 escaped
note ("The Kid&#x27;s Family") would migrate with the corruption preserved. Fixed:
element-transform.ts parseSpanNote now decodes via the pure decodeHtmlEntities
(matching SaveElement/ExportWorld). Propagates to every span-read path (migration,
readElement span fallback). 21/21 tests pass.

SMOKE-CHECKLIST.md: added the copy/throwaway-vault-first caution as the first line.

Also folds in a working-tree safety change to MigrateWorldCommand + main.ts that I
did NOT author (a teammate added it mid-flight): migration takes auto-sync's
markSelfWrite guard so a user with auto-sync on doesn't mass-PATCH migrated notes
to the server (which would break backup-based reversibility). Sound change; added
the null-guard (this.autoSync?.) it was missing so tsc passes. Flagged to lead.

Gate: tsc clean, esbuild build succeeds, npm test 21/21.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-16 13:49:32 +02:00
Titus
37c3f57a9b Rename local fetch closure in NoteLinker to avoid shadowing global
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-16 13:44:30 +02:00
Titus
59feec9338 Phase B: frontmatter flip (span -> YAML frontmatter)
Wake the dormant vault/element-file.ts write path and make YAML frontmatter
the note format for new writes, with read-tolerance for legacy span notes.

Pure logic (Obsidian-free, unit-tested under `npm test`):
- vault/element-transform.ts: frontmatter<->payload, span parse, span->frontmatter,
  link normalization (single string / multi list, never comma-joined), extension-key
  passthrough (atlas_/shadow_/x_), body<->description|story mapping, read-before-PATCH diff.
- test/element-transform.test.ts + tsconfig.test.json: 16 node:test cases incl. a real
  span-format Character fixture. Wired to `npm test` (pretest compiles to test-dist/).

Wiring:
- element-file.ts: readElement preserves extension fields + maps body to story for
  Narrative (R3/R5); frontmatter-first with legacy span fallback; writeElement round-trips
  extension keys and respects count-suffixed folders.
- DownloadWorldCommand + CreateElementCommand: emit frontmatter via writeElement (no more
  Handlebars element templates).
- NoteLinker: reworked onto metadataCache + SDK FIELD_SCHEMA; writes link IDs into
  frontmatter (new FieldSelectionModal picks the field). NameChanger syncs frontmatter name.
- SaveElementCommand: read-before-PATCH (GET, diff, PATCH only changed fields) (R7).
- ExportWorldCommand + CopyWorldCommand: read frontmatter via readElement, span as fallback
  (mixed worlds upload/copy correctly).
- MigrateWorldCommand: "Migrate world notes to frontmatter" — backup-first (abort on failure),
  idempotent, end report modal (converted/skipped/failed).

Deferred (see docs report): PasteWorld still emits span; ValidateWorld is still a span linter
(diagnostic only, no writes). docs/SMOKE-CHECKLIST.md is the manual release gate.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-16 13:43:56 +02:00
Titus
442465ec81 2.3.0 2026-07-13 18:22:34 +02:00
Titus
a5cf498ed7 2.3.0: OnlyWorlds v2 API transport + smoke-hardened sync + Delete Element
- All sync paths on /api/v2: Download World = /changes cursor walk (incremental
  re-downloads, rewind detection, honest delete reporting); Upload World =
  create/update sweep via /bulk + PATCH (server-only elements never deleted);
  Save/auto-sync via shared V2Client. Legacy worldsync routes fully retired.
- Filename sanitization: Windows-illegal chars (':' etc.) no longer mangle
  notes into NTFS streams; wikilinks use sanitized targets, names stay exact.
- Link safety: unresolvable links skip the whole field (server values kept,
  surfaced in a toast); uuid-shaped wikilinks pass through as ids.
- Delete Element command: typed-name confirm -> server DELETE -> note to trash.
- Progress toasts for download/upload; README rewritten (v2 semantics +
  ecosystem section).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-13 18:22:24 +02:00
Titus
3f23a3100c restore manifest version field (bad version-bump run dropped it)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-12 16:44:09 +02:00
Titus
440a378f9e 2.2.2
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-12 16:43:42 +02:00
Titus
73e7615dd1 fix HTML-entity escaping of names (apostrophes) in note write + read paths (2.2.2)
Handlebars default-escaped field values into note files; every read shipped
the escaped form (failed [[link]] file lookups, escaped names stored via API).
noEscape on all 5 compile sites + entity decode at every extraction seam.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-12 16:43:24 +02:00
Titus
b71bf16e90 2.2.1 docs: Download World + Upload World in README; drop dev checklist
README documented the stale 'Export World' palette name and never listed
the restored Download World command. Fixed both; removed the dev-only
TEST-CHECKLIST.md (carried an absolute local path).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-12 15:01:18 +02:00
Titus
05aac46cc0 2.2.1 2026-07-12 14:52:55 +02:00
Titus
734b32d77b fix wrong-world writes + false-success rename toast (2.2.1)
The wrong-world write class: per-world commands fell back to the settings
key whenever a world's own World.md key was missing, silently writing to
whatever world that key named. The settings key survives a vault-content
clear (.obsidian/data.json), so a read-key download + stale settings key
routed rename/save to the settings world. Shared resolveWorldKey() now
uses the world's OWN key; settings is fallback ONLY when the world has
none, and the fallback warns.

Rename false-success: the toast fired on the local rename before the API
PATCH ran, so a read-key (or any failed) push still said 'success'. Now
the push runs first and the notice states plainly whether onlyworlds.com
was updated or only the vault.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-12 14:52:40 +02:00
Titus
3e1725918e 2.2.0: Download World restored, round-trip link integrity, key-format sweep
Save Element creates new elements (create-on-404); Upload World renamed
with real error surfacing; Rename World pushes; Download World returns
(prefixed-key clean) with self-healing Map/Pin/Marker templates; upload
parser ships links as _id/_ids UUIDs; per-world key resolution ends the
wrong-world write class; scoped keys primary in all copy.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-12 13:56:56 +02:00
Titus
6bb07d21c1 2.1.0: retire legacy Import World command (prefixed-key readiness)
The legacy ImportWorldCommand + WorldImportModal enforced 10-digit
numeric API keys (digit-strip listener, maxlength, length checks) and
would reject the new prefixed ow_* keys the OnlyWorlds platform issues
after its backend migration. The SDK settings flow (link world + sync)
covers the import job with opaque-string key handling; old 10-digit
keys keep working there too.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-11 11:57:21 +02:00
Titus
6468e7d5e9 2.0.1: mobile support, drop FileSystemAdapter instanceof checks 2026-05-11 13:20:56 +02:00
tmoosting
8f6f893c05
Update README for clarity and consistency 2026-05-11 13:05:02 +02:00
tmoosting
04456b6987
Merge pull request #4 from OnlyWorlds/rebuild-2.0
2.0.0: SDK, auto-sync, native settings, modernized build
2026-05-11 12:54:21 +02:00
tmoosting
67f34ce424
Merge branch 'main' into rebuild-2.0 2026-05-11 12:54:07 +02:00
Titus
87e003e2e7 2.0.0: SDK, auto-sync, native settings, modernized build
Major rebuild. Plugin now uses @onlyworlds/sdk for API calls via Obsidian's
requestUrl, native PluginSettingTab for configuration, and a debounced auto-sync
engine that pushes element edits to onlyworlds.com after idle.

Changes
- Drop handrolled API code; route all writes through @onlyworlds/sdk subclass
- Native settings tab: API key, PIN, default world, sync mode, debounce
- PIN handling: persist in settings or cache per session; no per-save prompts
- Auto-sync toggle with configurable debounce (default 3s)
- Status bar + ribbon icon reflect sync state (idle/dirty/syncing/synced/error)
- Ribbon click opens menu (Sync / Settings / About) instead of firing sync
- Settings API key wins over per-world World.md (legacy fallback preserved)
- Add Map, Pin, Marker to element category enum (now 22)
- ESLint config (eslint-plugin-obsidianmd) scoped to new code
- Modernize build: TS 5.8, esbuild 0.25, stricter tsconfig
- Drop dead code: GraphViewExtensions, dead command imports, handleApiError

Compatibility
- Existing v1 vaults work unchanged. Span-tag format preserved.
- OnlyWorlds/Settings.md still readable; new settings tab takes precedence.
- isDesktopOnly: true. Mobile pending verification.
2026-05-11 12:51:28 +02:00
tmoosting
ea47d43cd0
Update README.md 2026-02-14 10:25:09 +01:00
Titus
aece64acfb update readme 2025-11-16 15:05:55 +01:00
Titus
59f1cc109a readme 2025-11-16 14:57:45 +01:00
tmoosting
24bd05ccc4
Update README.md 2025-07-09 12:30:51 +02:00
Titus
c0588f417f update vrsion 2025-07-09 12:18:17 +02:00
Titus
3ad600052d new version for styles include 2025-07-09 12:13:20 +02:00
Titus
2db39c7c7b Enhance NoteLinker and CreateElementCommand with manifest integration; add CreateElementFromLinkModal for element creation. Update ElementSelectionModal to support new element creation and refresh functionality. 2025-07-09 09:47:30 +02:00
Titus
748c67a968 export copy save errors, folder rename race fix 2025-07-08 21:34:08 +02:00
tmoosting
2895d6cfe4
Merge pull request #3 from OnlyWorlds/0030-refactor
0030 refactor
2025-07-08 20:13:47 +02:00