wiki-plugin-hearth 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,8 @@
1
+ (()=>{var i=e=>String(e).replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;"),p=e=>{let t={notice:"This page keeps to its hearth. Please do not republish it outside its home.",expires:""};for(let r of(e||"").split(/\n/)){let n=r.match(/^([A-Z]+):?\s+(.*)$/);if(!n)continue;let[,a,s]=n;a==="NOTE"&&(t.notice=s.trim()||t.notice),a==="EXPIRES"&&(t.expires=s.trim())}return t},c=(e,t=Date.now())=>{if(!e)return"";let r=Date.parse(e.replace(/Z$/,"Z"));if(Number.isNaN(r))return"";let n=Math.round((r-t)/1e3);if(n<=0)return"expired";let a=Math.floor(n/86400),s=Math.floor(n%86400/3600),o=Math.floor(n%3600/60);return a?`disappears in ${a}d ${s}h`:s?`disappears in ${s}h ${o}m`:`disappears in ${o}m`},d=(e,t)=>{let r=p(t.text||"");e.parents(".page").addClass("hearth-page");let a=c(r.expires);e.html(`
2
+ <div class="hearth-mark" style="display:flex;gap:8px;align-items:center;padding:8px 10px;border-radius:6px;background:rgba(200,120,40,0.12);border:1px solid rgba(200,120,40,0.4);font-size:0.85em;">
3
+ <span aria-hidden="true" style="font-size:1.3em;">\u{1F3E0}</span>
4
+ <span class="hearth-notice">${i(r.notice)}</span>
5
+ ${a?`<span class="hearth-expiry" style="margin-left:auto;color:#a05000;font-family:ui-monospace,monospace;">${i(a)}</span>`:""}
6
+ </div>
7
+ `)},l=(e,t)=>{e.find(".hearth-mark").on("dblclick",()=>wiki.textEditor(e,t))};if(typeof window<"u"&&(window.plugins=window.plugins||{},window.plugins.hearth={emit:d,bind:l},!document.getElementById("hearth-style"))){let e=document.createElement("style");e.id="hearth-style",e.textContent=".page.hearth-page{box-shadow:inset 0 0 0 3px rgba(200,120,40,0.5),0 0 22px rgba(200,120,40,0.35);background:linear-gradient(rgba(200,120,40,0.05),rgba(200,120,40,0.05));}",document.head.appendChild(e)}})();
8
+ //# sourceMappingURL=hearth.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/client/hearth.js"],
4
+ "sourcesContent": ["/*\n * Federated Wiki : Hearth Plugin\n *\n * A `hearth` item marks a page as keeping to its hearth \u2014 meant to stay in the\n * private space it was written in. On render it tints the whole page with a\n * warm halo and shows its own plain-text notice, so even a copy that escapes to\n * a wiki without our client still carries the words that ask it home.\n *\n * The teeth \u2014 blocking fork, drag-out and drop-in \u2014 live in wiki-plugin-hitchhiker's\n * wiki-ux.js, which runs farm-wide and detects this item by the `hearth-page`\n * class this file adds. See the hearth-pages spec on mouse.localhost.\n *\n * Licensed under the MIT license.\n */\n\nconst escapeHtml = s =>\n String(s).replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/\"/g, '&quot;')\n\n// fedwiki-dsl: UPPERCASE first word = command, optional trailing colon.\n// NOTE line adds a custom notice; EXPIRES <iso> declares a disappearing page\n// (the reaper reads it server-side; here we just surface it).\nexport const parse = text => {\n const opts = {\n notice: 'This page keeps to its hearth. Please do not republish it outside its home.',\n expires: '',\n }\n for (const line of (text || '').split(/\\n/)) {\n const m = line.match(/^([A-Z]+):?\\s+(.*)$/)\n if (!m) continue\n const [, cmd, arg] = m\n if (cmd === 'NOTE') opts.notice = arg.trim() || opts.notice\n if (cmd === 'EXPIRES') opts.expires = arg.trim()\n }\n return opts\n}\n\n// A human, timezone-aware countdown, or '' when not expiring / already past.\nexport const countdown = (expires, now = Date.now()) => {\n if (!expires) return ''\n const when = Date.parse(expires.replace(/Z$/, 'Z'))\n if (Number.isNaN(when)) return ''\n const secs = Math.round((when - now) / 1000)\n if (secs <= 0) return 'expired'\n const d = Math.floor(secs / 86400)\n const h = Math.floor((secs % 86400) / 3600)\n const m = Math.floor((secs % 3600) / 60)\n if (d) return `disappears in ${d}d ${h}h`\n if (h) return `disappears in ${h}h ${m}m`\n return `disappears in ${m}m`\n}\n\nexport const emit = (div, item) => {\n const opts = parse(item.text || '')\n const $page = div.parents('.page')\n $page.addClass('hearth-page')\n\n const cd = countdown(opts.expires)\n div.html(`\n <div class=\"hearth-mark\" style=\"display:flex;gap:8px;align-items:center;padding:8px 10px;border-radius:6px;background:rgba(200,120,40,0.12);border:1px solid rgba(200,120,40,0.4);font-size:0.85em;\">\n <span aria-hidden=\"true\" style=\"font-size:1.3em;\">\\u{1F3E0}</span>\n <span class=\"hearth-notice\">${escapeHtml(opts.notice)}</span>\n ${cd ? `<span class=\"hearth-expiry\" style=\"margin-left:auto;color:#a05000;font-family:ui-monospace,monospace;\">${escapeHtml(cd)}</span>` : ''}\n </div>\n `)\n}\n\nexport const bind = (div, item) => {\n div.find('.hearth-mark').on('dblclick', () => wiki.textEditor(div, item))\n}\n\nif (typeof window !== 'undefined') {\n window.plugins = window.plugins || {}\n window.plugins['hearth'] = { emit, bind }\n\n // Farm-wide halo \u2014 injected once. wiki-plugin-hitchhiker styles it further.\n if (!document.getElementById('hearth-style')) {\n const s = document.createElement('style')\n s.id = 'hearth-style'\n s.textContent =\n '.page.hearth-page{box-shadow:inset 0 0 0 3px rgba(200,120,40,0.5),0 0 22px rgba(200,120,40,0.35);' +\n 'background:linear-gradient(rgba(200,120,40,0.05),rgba(200,120,40,0.05));}'\n document.head.appendChild(s)\n }\n}\n"],
5
+ "mappings": "MAeA,IAAMA,EAAaC,GACjB,OAAOA,CAAC,EAAE,QAAQ,KAAM,OAAO,EAAE,QAAQ,KAAM,MAAM,EAAE,QAAQ,KAAM,MAAM,EAAE,QAAQ,KAAM,QAAQ,EAKxFC,EAAQC,GAAQ,CAC3B,IAAMC,EAAO,CACX,OAAQ,8EACR,QAAS,EACX,EACA,QAAWC,KAASF,GAAQ,IAAI,MAAM,IAAI,EAAG,CAC3C,IAAMG,EAAID,EAAK,MAAM,qBAAqB,EAC1C,GAAI,CAACC,EAAG,SACR,GAAM,CAAC,CAAEC,EAAKC,CAAG,EAAIF,EACjBC,IAAQ,SAAQH,EAAK,OAASI,EAAI,KAAK,GAAKJ,EAAK,QACjDG,IAAQ,YAAWH,EAAK,QAAUI,EAAI,KAAK,EACjD,CACA,OAAOJ,CACT,EAGaK,EAAY,CAACC,EAASC,EAAM,KAAK,IAAI,IAAM,CACtD,GAAI,CAACD,EAAS,MAAO,GACrB,IAAME,EAAO,KAAK,MAAMF,EAAQ,QAAQ,KAAM,GAAG,CAAC,EAClD,GAAI,OAAO,MAAME,CAAI,EAAG,MAAO,GAC/B,IAAMC,EAAO,KAAK,OAAOD,EAAOD,GAAO,GAAI,EAC3C,GAAIE,GAAQ,EAAG,MAAO,UACtB,IAAMC,EAAI,KAAK,MAAMD,EAAO,KAAK,EAC3BE,EAAI,KAAK,MAAOF,EAAO,MAAS,IAAI,EACpCP,EAAI,KAAK,MAAOO,EAAO,KAAQ,EAAE,EACvC,OAAIC,EAAU,iBAAiBA,CAAC,KAAKC,CAAC,IAClCA,EAAU,iBAAiBA,CAAC,KAAKT,CAAC,IAC/B,iBAAiBA,CAAC,GAC3B,EAEaU,EAAO,CAACC,EAAKC,IAAS,CACjC,IAAMd,EAAOF,EAAMgB,EAAK,MAAQ,EAAE,EACpBD,EAAI,QAAQ,OAAO,EAC3B,SAAS,aAAa,EAE5B,IAAME,EAAKV,EAAUL,EAAK,OAAO,EACjCa,EAAI,KAAK;AAAA;AAAA;AAAA,oCAGyBjB,EAAWI,EAAK,MAAM,CAAC;AAAA,QACnDe,EAAK,0GAA0GnB,EAAWmB,CAAE,CAAC,UAAY,EAAE;AAAA;AAAA,GAEhJ,CACH,EAEaC,EAAO,CAACH,EAAKC,IAAS,CACjCD,EAAI,KAAK,cAAc,EAAE,GAAG,WAAY,IAAM,KAAK,WAAWA,EAAKC,CAAI,CAAC,CAC1E,EAEA,GAAI,OAAO,OAAW,MACpB,OAAO,QAAU,OAAO,SAAW,CAAC,EACpC,OAAO,QAAQ,OAAY,CAAE,KAAAF,EAAM,KAAAI,CAAK,EAGpC,CAAC,SAAS,eAAe,cAAc,GAAG,CAC5C,IAAMnB,EAAI,SAAS,cAAc,OAAO,EACxCA,EAAE,GAAK,eACPA,EAAE,YACA,6KAEF,SAAS,KAAK,YAAYA,CAAC,CAC7B",
6
+ "names": ["escapeHtml", "s", "parse", "text", "opts", "line", "m", "cmd", "arg", "countdown", "expires", "now", "when", "secs", "d", "h", "emit", "div", "item", "cd", "bind"]
7
+ }
package/factory.json ADDED
@@ -0,0 +1 @@
1
+ {"name": "Hearth", "title": "Mark this page as keeping to its hearth — halo, and hard to publish outside its home", "category": "other"}
package/package.json ADDED
@@ -0,0 +1,19 @@
1
+ {
2
+ "name": "wiki-plugin-hearth",
3
+ "version": "0.1.0",
4
+ "description": "Federated Wiki hearth item — marks a page as keeping to its hearth: a coloured halo, and (with wiki-plugin-hitchhiker) hard to fork or publish outside its home farm.",
5
+ "type": "module",
6
+ "main": "client/hearth.js",
7
+ "files": ["client", "pages", "factory.json"],
8
+ "scripts": {
9
+ "build": "node scripts/build.js",
10
+ "test": "node --test"
11
+ },
12
+ "dependencies": {},
13
+ "devDependencies": { "esbuild": "^0.25.0" },
14
+ "author": "David Bovill",
15
+ "license": "MIT",
16
+ "repository": { "type": "git", "url": "git+https://github.com/Hitchhikers-Guide-to-the-Galaxy/wiki-plugin-hearth.git" },
17
+ "bugs": { "url": "https://github.com/Hitchhikers-Guide-to-the-Galaxy/wiki-plugin-hearth/issues" },
18
+ "homepage": "https://github.com/Hitchhikers-Guide-to-the-Galaxy/wiki-plugin-hearth#readme"
19
+ }
@@ -0,0 +1,100 @@
1
+ {
2
+ "title": "About Hearth Plugin",
3
+ "story": [
4
+ {
5
+ "type": "markdown",
6
+ "id": "632dcee19d39899f",
7
+ "text": "The **Hearth Plugin**, `wiki-plugin-hearth`, marks a page as keeping to its hearth — meant to stay in the space it was written in. The `hearth` item paints the page with a warm halo and a plain notice, and, where the hitchhiker UX layer runs, makes the page hard to fork or publish out."
8
+ },
9
+ {
10
+ "type": "markdown",
11
+ "id": "431e4984677c0378",
12
+ "text": "## Repositories\n\n- [https://github.com/Hitchhikers-Guide-to-the-Galaxy/wiki-plugin-hearth github]\n- [https://www.npmjs.com/package/wiki-plugin-hearth npm]"
13
+ },
14
+ {
15
+ "type": "markdown",
16
+ "id": "4c66a11aaef72ada",
17
+ "text": "## Item Text\n\nCommands follow the wiki DSL convention: uppercase first word, optional colon.\n\n- `NOTE <text>` overrides the notice shown on the page.\n- `EXPIRES <iso>` declares a disappearing page — a reaper reads it server-side to hard-delete the page once past."
18
+ },
19
+ {
20
+ "type": "code",
21
+ "id": "6183a191ba2b4a79",
22
+ "text": "NOTE Mice only — keeps to the private farm.\nEXPIRES 2026-07-14T18:00Z",
23
+ "language": "text"
24
+ },
25
+ {
26
+ "type": "markdown",
27
+ "id": "94e6c064fce615da",
28
+ "text": "## The Halo and the Poison Pill\n\nOn render the item adds a `hearth-page` class to the whole page (the halo CSS) and shows its notice. Because story items travel with a fork, an escaped copy still renders the notice on any farm running the plugin — and shows the raw words even on one that does not. The mark asks the page home wherever it lands."
29
+ },
30
+ {
31
+ "type": "markdown",
32
+ "id": "75f3d9fb92f34d8b",
33
+ "text": "## The Teeth\n\nEnforcement lives in the hitchhiker UX layer (`wiki-plugin-hitchhiker`), farm-wide: a capture listener blocks dragging a hearth page's flag out, and the drop handler refuses to import a hearth-marked page. Enforcement is total only where that client runs; elsewhere the mark is etiquette, friction and provenance. Soft security by design."
34
+ },
35
+ {
36
+ "type": "markdown",
37
+ "id": "42ad5913edbbcd15",
38
+ "text": "## Requirements\n\nClient-only, no server component. The halo and notice render anywhere the plugin is installed. The fork and drop blocks require `wiki-plugin-hitchhiker`; the disappearing-page reaper is a separate scheduled script."
39
+ },
40
+ {
41
+ "type": "markdown",
42
+ "id": "6996e880339a8dd8",
43
+ "text": "# See\n\n- [[Index Of Plugins]]\n- [[Chat Plugin]]"
44
+ }
45
+ ],
46
+ "plugin": "hearth",
47
+ "journal": [
48
+ {
49
+ "type": "create",
50
+ "item": {
51
+ "title": "About Hearth Plugin",
52
+ "story": [
53
+ {
54
+ "type": "markdown",
55
+ "id": "632dcee19d39899f",
56
+ "text": "The **Hearth Plugin**, `wiki-plugin-hearth`, marks a page as keeping to its hearth — meant to stay in the space it was written in. The `hearth` item paints the page with a warm halo and a plain notice, and, where the hitchhiker UX layer runs, makes the page hard to fork or publish out."
57
+ },
58
+ {
59
+ "type": "markdown",
60
+ "id": "431e4984677c0378",
61
+ "text": "## Repositories\n\n- [https://github.com/Hitchhikers-Guide-to-the-Galaxy/wiki-plugin-hearth github]\n- [https://www.npmjs.com/package/wiki-plugin-hearth npm]"
62
+ },
63
+ {
64
+ "type": "markdown",
65
+ "id": "4c66a11aaef72ada",
66
+ "text": "## Item Text\n\nCommands follow the wiki DSL convention: uppercase first word, optional colon.\n\n- `NOTE <text>` overrides the notice shown on the page.\n- `EXPIRES <iso>` declares a disappearing page — a reaper reads it server-side to hard-delete the page once past."
67
+ },
68
+ {
69
+ "type": "code",
70
+ "id": "6183a191ba2b4a79",
71
+ "text": "NOTE Mice only — keeps to the private farm.\nEXPIRES 2026-07-14T18:00Z",
72
+ "language": "text"
73
+ },
74
+ {
75
+ "type": "markdown",
76
+ "id": "94e6c064fce615da",
77
+ "text": "## The Halo and the Poison Pill\n\nOn render the item adds a `hearth-page` class to the whole page (the halo CSS) and shows its notice. Because story items travel with a fork, an escaped copy still renders the notice on any farm running the plugin — and shows the raw words even on one that does not. The mark asks the page home wherever it lands."
78
+ },
79
+ {
80
+ "type": "markdown",
81
+ "id": "75f3d9fb92f34d8b",
82
+ "text": "## The Teeth\n\nEnforcement lives in the hitchhiker UX layer (`wiki-plugin-hitchhiker`), farm-wide: a capture listener blocks dragging a hearth page's flag out, and the drop handler refuses to import a hearth-marked page. Enforcement is total only where that client runs; elsewhere the mark is etiquette, friction and provenance. Soft security by design."
83
+ },
84
+ {
85
+ "type": "markdown",
86
+ "id": "42ad5913edbbcd15",
87
+ "text": "## Requirements\n\nClient-only, no server component. The halo and notice render anywhere the plugin is installed. The fork and drop blocks require `wiki-plugin-hitchhiker`; the disappearing-page reaper is a separate scheduled script."
88
+ },
89
+ {
90
+ "type": "markdown",
91
+ "id": "6996e880339a8dd8",
92
+ "text": "# See\n\n- [[Index Of Plugins]]\n- [[Chat Plugin]]"
93
+ }
94
+ ]
95
+ },
96
+ "date": 1783860621343,
97
+ "provenance": "Authored by an AI agent — Claude Code (claude-fable-5) via the [[fedwiki-page]] skill. [https://claude.com/claude-code Claude Code]"
98
+ }
99
+ ]
100
+ }