codebay 0.0.1 → 0.2.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.
Files changed (202) hide show
  1. package/.mochi/import-css/index-0nwv3654.css +18 -0
  2. package/.mochi/import-css/index-xndx4980.css +54 -0
  3. package/.mochi/manifest.json +1608 -0
  4. package/.mochi/server-island.js +1 -0
  5. package/.mochi/svelte-client/HydratableIsland-ps09gjy2.js +1 -0
  6. package/.mochi/svelte-client/_hydrate-AppShell_2rtnxn6pgp2rh-62w5zwww.js +2 -0
  7. package/.mochi/svelte-client/_hydrate-AvatarsView_257s9yq1wwr4f-jmm501zf.js +13 -0
  8. package/.mochi/svelte-client/_hydrate-InstanceView_2ma45l9bybfhl-ewk4n2c0.js +1 -0
  9. package/.mochi/svelte-client/_hydrate-SettingsView_8hmarwmf8onq-e7e89md0.js +23 -0
  10. package/.mochi/svelte-client/chunk-jx5cekhh.js +2 -0
  11. package/.mochi/svelte-client/chunk-k3my1snp.js +2 -0
  12. package/.mochi/svelte-client/chunk-kgn1b2t1.js +4 -0
  13. package/.mochi/svelte-client/chunk-ry7q5zk5.js +1 -0
  14. package/.mochi/svelte-client/chunk-x843txjc.js +2 -0
  15. package/.mochi/svelte-client/chunk-zjcg8kw5.js +2 -0
  16. package/.mochi/svelte-compile/App-8k1gyxdc.server.js +1167 -0
  17. package/.mochi/svelte-compile/Avatars-f7c6rp96.server.js +351 -0
  18. package/.mochi/svelte-compile/ClientStats-z3tn9ad6.server.js +99 -0
  19. package/.mochi/svelte-compile/DefaultError-wh77vebf.server.js +52 -0
  20. package/.mochi/svelte-compile/Instance-yvps12zg.server.js +355 -0
  21. package/.mochi/svelte-compile/Settings-jwg3httb.server.js +1169 -0
  22. package/.mochi/svelte-compile/chunk-4kwy539a.js +14 -0
  23. package/.mochi/svelte-compile/chunk-9bjk7yx6.js +81 -0
  24. package/.mochi/svelte-compile/chunk-dqgstte4.js +52 -0
  25. package/.mochi/svelte-compile/chunk-sxqys3nw.js +1668 -0
  26. package/.mochi/svelte-compile/chunk-v6796ga4.js +3295 -0
  27. package/.mochi/svelte-compile/chunk-we0ggtws.js +34 -0
  28. package/.mochi/svelte-css/AppBar-3bxinv4pabv8l.css +1 -0
  29. package/.mochi/svelte-css/AppShell-36mpg5smnbmuw.css +1 -0
  30. package/.mochi/svelte-css/Avatar-24th63awm9mna.css +1 -0
  31. package/.mochi/svelte-css/AvatarEditor-1ryrs1md5g36y.css +1 -0
  32. package/.mochi/svelte-css/AvatarsView-3hq37u4dgtljn.css +1 -0
  33. package/.mochi/svelte-css/BackLink-2wlu0eovz9j86.css +1 -0
  34. package/.mochi/svelte-css/BranchBox-1yqu1q2mgnjwz.css +1 -0
  35. package/.mochi/svelte-css/Brand-1la7zw5uhcbl4.css +1 -0
  36. package/.mochi/svelte-css/Button-2vtbrzb5kgu25.css +1 -0
  37. package/.mochi/svelte-css/CheckmarkIcon-3qlazj2oc50jc.css +1 -0
  38. package/.mochi/svelte-css/ClientStats-19qzckq40p2q9.css +1 -0
  39. package/.mochi/svelte-css/CoinButton-1rej3sh3tkjud.css +1 -0
  40. package/.mochi/svelte-css/CredMenu-9hwgeptp7crb.css +1 -0
  41. package/.mochi/svelte-css/DashboardView-1cy4xpqhja9sx.css +1 -0
  42. package/.mochi/svelte-css/DefaultError-2b0daamydxgb2.css +1 -0
  43. package/.mochi/svelte-css/ErrorIcon-2x0tzsqxskw28.css +1 -0
  44. package/.mochi/svelte-css/FolderBrowser-1x428zb3f2kti.css +1 -0
  45. package/.mochi/svelte-css/HealthBox-er2her0jukwl.css +1 -0
  46. package/.mochi/svelte-css/IdeBar-2qoqi2ya9zdn3.css +1 -0
  47. package/.mochi/svelte-css/IdeLoader-26rlko8e00j3g.css +1 -0
  48. package/.mochi/svelte-css/InstanceCard-16f77aysm7lgp.css +1 -0
  49. package/.mochi/svelte-css/InstanceView-wq85bxtusont.css +1 -0
  50. package/.mochi/svelte-css/LoaderIcon-soq5wt3p05ye.css +1 -0
  51. package/.mochi/svelte-css/PortsBox-1t25b5yg7jva3.css +1 -0
  52. package/.mochi/svelte-css/SettingsCog-jftyadvo64qo.css +1 -0
  53. package/.mochi/svelte-css/SettingsView-3bbkzsvnrth3v.css +1 -0
  54. package/.mochi/svelte-css/Skeleton-8k69usiju43h.css +1 -0
  55. package/.mochi/svelte-css/StatusBadge-3mq0j7z6aq4j.css +1 -0
  56. package/.mochi/svelte-css/ThemePicker-1ir8jyocm8mvi.css +1 -0
  57. package/.mochi/svelte-css/ToastBar-3havgkmtofntq.css +1 -0
  58. package/.mochi/svelte-css/ToastIcon-2z5wrkc95khg0.css +1 -0
  59. package/.mochi/svelte-css/ToastMessage-2jfwb2og2lfa8.css +1 -0
  60. package/.mochi/svelte-css/ToastWrapper-1fbnym10rm2nv.css +1 -0
  61. package/.mochi/svelte-css/Toaster-kk60j193854n.css +1 -0
  62. package/.mochi/svelte-css/TopBar-2q87li6yt8ids.css +1 -0
  63. package/LICENSE +21 -0
  64. package/README.md +33 -3
  65. package/bin/codebay.ts +22 -0
  66. package/migrations/0001_init.sql +20 -0
  67. package/migrations/0002_port_forwards.sql +9 -0
  68. package/migrations/0003_options.sql +4 -0
  69. package/migrations/0004_instance_image.sql +1 -0
  70. package/package.json +87 -9
  71. package/public/sounds/done.wav +0 -0
  72. package/public/sounds/waiting.wav +0 -0
  73. package/src/__fixtures__/HelloWorld.svelte +4 -0
  74. package/src/additional-svelte-typings.d.ts +1 -0
  75. package/src/api.ts +61 -0
  76. package/src/avatars/anchor.ts +17 -0
  77. package/src/avatars/bear.ts +17 -0
  78. package/src/avatars/bee.ts +17 -0
  79. package/src/avatars/bob-marley.ts +17 -0
  80. package/src/avatars/car.ts +17 -0
  81. package/src/avatars/carpathians.ts +17 -0
  82. package/src/avatars/cat-body.ts +17 -0
  83. package/src/avatars/cat-sits.ts +17 -0
  84. package/src/avatars/cat.ts +17 -0
  85. package/src/avatars/celtic-cross.ts +17 -0
  86. package/src/avatars/cherry.ts +17 -0
  87. package/src/avatars/cotton.ts +17 -0
  88. package/src/avatars/crab.ts +17 -0
  89. package/src/avatars/crown.ts +17 -0
  90. package/src/avatars/diamond.ts +17 -0
  91. package/src/avatars/dog.ts +17 -0
  92. package/src/avatars/elephant.ts +17 -0
  93. package/src/avatars/fish.ts +17 -0
  94. package/src/avatars/fleur-de-lis.ts +17 -0
  95. package/src/avatars/flower.ts +17 -0
  96. package/src/avatars/fox.ts +17 -0
  97. package/src/avatars/frog.ts +17 -0
  98. package/src/avatars/ghost.ts +17 -0
  99. package/src/avatars/giraffe.ts +17 -0
  100. package/src/avatars/glasses.ts +17 -0
  101. package/src/avatars/heart.ts +17 -0
  102. package/src/avatars/index.ts +128 -0
  103. package/src/avatars/invader.ts +17 -0
  104. package/src/avatars/kangaroo.ts +17 -0
  105. package/src/avatars/key.ts +17 -0
  106. package/src/avatars/lightning.ts +17 -0
  107. package/src/avatars/mushroom.ts +17 -0
  108. package/src/avatars/octopus.ts +17 -0
  109. package/src/avatars/owl.ts +17 -0
  110. package/src/avatars/penguin.ts +17 -0
  111. package/src/avatars/planet.ts +17 -0
  112. package/src/avatars/rabbit.ts +17 -0
  113. package/src/avatars/rat.ts +17 -0
  114. package/src/avatars/robot.ts +17 -0
  115. package/src/avatars/rocket.ts +17 -0
  116. package/src/avatars/sea.ts +17 -0
  117. package/src/avatars/serialize.ts +65 -0
  118. package/src/avatars/skull.ts +17 -0
  119. package/src/avatars/snail.ts +17 -0
  120. package/src/avatars/snake.ts +17 -0
  121. package/src/avatars/snakegame.ts +17 -0
  122. package/src/avatars/star.ts +17 -0
  123. package/src/avatars/svelte.ts +17 -0
  124. package/src/avatars/target.ts +17 -0
  125. package/src/avatars/tree.ts +17 -0
  126. package/src/avatars/types.ts +24 -0
  127. package/src/avatars/ukraine.ts +17 -0
  128. package/src/avatars/whale.ts +17 -0
  129. package/src/avatars/wheat.ts +17 -0
  130. package/src/avatars/yinyan.ts +17 -0
  131. package/src/components/AppBar.svelte +35 -0
  132. package/src/components/AppShell.svelte +302 -0
  133. package/src/components/Avatar.svelte +235 -0
  134. package/src/components/AvatarEditor.svelte +321 -0
  135. package/src/components/AvatarsView.svelte +113 -0
  136. package/src/components/BranchBox.svelte +32 -0
  137. package/src/components/Brand.svelte +41 -0
  138. package/src/components/Button.svelte +161 -0
  139. package/src/components/CoinButton.svelte +121 -0
  140. package/src/components/CredMenu.svelte +171 -0
  141. package/src/components/DashboardView.svelte +198 -0
  142. package/src/components/FolderBrowser.svelte +635 -0
  143. package/src/components/HealthBox.svelte +161 -0
  144. package/src/components/IdeBar.svelte +186 -0
  145. package/src/components/IdeLoader.svelte +135 -0
  146. package/src/components/InstanceCard.svelte +220 -0
  147. package/src/components/InstanceView.svelte +565 -0
  148. package/src/components/PortsBox.svelte +73 -0
  149. package/src/components/SettingsCog.svelte +22 -0
  150. package/src/components/SettingsView.svelte +1484 -0
  151. package/src/components/Skeleton.svelte +43 -0
  152. package/src/components/StatusBadge.svelte +54 -0
  153. package/src/components/ThemePicker.svelte +77 -0
  154. package/src/components/TopBar.svelte +64 -0
  155. package/src/components/UiShowcase.svelte +578 -0
  156. package/src/components/ui-showcase/ComponentDemo.svelte +85 -0
  157. package/src/container-injections/attention-hooks.ts +117 -0
  158. package/src/container-injections/claude-aliases.ts +43 -0
  159. package/src/container-injections/claude-code-credentials.ts +145 -0
  160. package/src/container-injections/claude-code-custom.ts +125 -0
  161. package/src/container-injections/claude-no-coauthor.ts +35 -0
  162. package/src/container-injections/claude-skip-permissions.ts +38 -0
  163. package/src/container-injections/claude-statusline.ts +109 -0
  164. package/src/container-injections/git-identity.ts +63 -0
  165. package/src/container-injections/git-safe-directory.ts +18 -0
  166. package/src/container-injections/github-credentials.ts +162 -0
  167. package/src/container-injections/host-env-vars.ts +108 -0
  168. package/src/container-injections/tmux.ts +67 -0
  169. package/src/fontsource.d.ts +3 -0
  170. package/src/index.ts +81 -0
  171. package/src/lib/auth.server.ts +95 -0
  172. package/src/lib/bridge.server.ts +34 -0
  173. package/src/lib/config.server.ts +122 -0
  174. package/src/lib/crypto.server.ts +12 -0
  175. package/src/lib/db.server.ts +196 -0
  176. package/src/lib/devcontainer.server.ts +503 -0
  177. package/src/lib/docker-client.server.ts +61 -0
  178. package/src/lib/docker.server.ts +139 -0
  179. package/src/lib/exec.server.ts +92 -0
  180. package/src/lib/git.server.ts +68 -0
  181. package/src/lib/health.server.ts +105 -0
  182. package/src/lib/injections.server.ts +72 -0
  183. package/src/lib/instances.server.ts +552 -0
  184. package/src/lib/picker.server.ts +46 -0
  185. package/src/lib/ports.server.ts +9 -0
  186. package/src/lib/proxy.server.ts +170 -0
  187. package/src/lib/repo-url.ts +60 -0
  188. package/src/lib/spawn.server.ts +14 -0
  189. package/src/lib/theme.server.ts +22 -0
  190. package/src/live.ts +50 -0
  191. package/src/pages/App.svelte +14 -0
  192. package/src/pages/Avatars.svelte +7 -0
  193. package/src/pages/Instance.svelte +9 -0
  194. package/src/pages/Settings.svelte +73 -0
  195. package/src/pages/UI.svelte +10 -0
  196. package/src/routes.ts +440 -0
  197. package/src/settings.ts +14 -0
  198. package/src/shell.html +100 -0
  199. package/src/sound.ts +69 -0
  200. package/src/theme.ts +24 -0
  201. package/src/types.ts +79 -0
  202. package/svelte.config.js +5 -0
@@ -0,0 +1,17 @@
1
+ import type { AvatarArt } from './types.ts';
2
+
3
+ const art: AvatarArt = {
4
+ name: 'penguin',
5
+ pixels: [
6
+ '..####..',
7
+ '.######.',
8
+ '.##..##.',
9
+ '.#.##.#.',
10
+ '##...##.',
11
+ '##...##.',
12
+ '#######.',
13
+ '.#....#.'
14
+ ]
15
+ };
16
+
17
+ export default art;
@@ -0,0 +1,17 @@
1
+ import type { AvatarArt } from './types.ts';
2
+
3
+ const art: AvatarArt = {
4
+ name: 'planet',
5
+ pixels: [
6
+ '...###..',
7
+ '..#####.',
8
+ '#.#####.',
9
+ '.#######',
10
+ '..#####.',
11
+ '..####..',
12
+ '.###....',
13
+ '........'
14
+ ]
15
+ };
16
+
17
+ export default art;
@@ -0,0 +1,17 @@
1
+ import type { AvatarArt } from './types.ts';
2
+
3
+ const art: AvatarArt = {
4
+ name: 'rabbit',
5
+ pixels: [
6
+ '.#....#.',
7
+ '.##..##.',
8
+ '.##..##.',
9
+ '..####..',
10
+ '.######.',
11
+ '###..###',
12
+ '#..##..#',
13
+ '.######.'
14
+ ]
15
+ };
16
+
17
+ export default art;
@@ -0,0 +1,17 @@
1
+ import type { AvatarArt } from './types.ts';
2
+
3
+ const art: AvatarArt = {
4
+ name: 'rat',
5
+ pixels: [
6
+ '...#.#..',
7
+ '...#####',
8
+ '...#.#..',
9
+ '..###...',
10
+ '.####.#.',
11
+ '#####..#',
12
+ '####..#.',
13
+ '.#####..'
14
+ ]
15
+ };
16
+
17
+ export default art;
@@ -0,0 +1,17 @@
1
+ import type { AvatarArt } from './types.ts';
2
+
3
+ const art: AvatarArt = {
4
+ name: 'robot',
5
+ pixels: [
6
+ '...##...',
7
+ '...#....',
8
+ '.######.',
9
+ '#.####.#',
10
+ '#..##..#',
11
+ '.######.',
12
+ '.#####..',
13
+ '.######.'
14
+ ]
15
+ };
16
+
17
+ export default art;
@@ -0,0 +1,17 @@
1
+ import type { AvatarArt } from './types.ts';
2
+
3
+ const art: AvatarArt = {
4
+ name: 'rocket',
5
+ pixels: [
6
+ '...##...',
7
+ '..####..',
8
+ '..#..#..',
9
+ '..####..',
10
+ '.######.',
11
+ '##.##.##',
12
+ '..#..#..',
13
+ '...##...'
14
+ ]
15
+ };
16
+
17
+ export default art;
@@ -0,0 +1,17 @@
1
+ import type { AvatarArt } from './types.ts';
2
+
3
+ const art: AvatarArt = {
4
+ name: 'sea',
5
+ pixels: [
6
+ '#.#.....',
7
+ '.#..#.#.',
8
+ '.....#..',
9
+ '...#....',
10
+ '........',
11
+ '########',
12
+ '.##..###',
13
+ '##.###..'
14
+ ]
15
+ };
16
+
17
+ export default art;
@@ -0,0 +1,65 @@
1
+ // Turns an avatar-editor drawing into the two things a contribution needs:
2
+ // module source and a pre-filled issue URL.
3
+ import { type AvatarArt, ROWS, COLS, ON } from './types.ts';
4
+
5
+ export const REPO_URL = 'https://github.com/khromov/codebay';
6
+
7
+ // The name doubles as a filename and a catalog key, hence the aggressive squash.
8
+ export function normalizeName(raw: string): string {
9
+ return raw
10
+ .trim()
11
+ .toLowerCase()
12
+ .replace(/[^a-z0-9-]+/g, '-')
13
+ .replace(/^-+|-+$/g, '');
14
+ }
15
+
16
+ export function cellsToPixels(cells: number[]): string[] {
17
+ const rows: string[] = [];
18
+ for (let r = 0; r < ROWS; r++) {
19
+ let row = '';
20
+ for (let c = 0; c < COLS; c++) {
21
+ row += cells[r * COLS + c] === ON ? '#' : '.';
22
+ }
23
+ rows.push(row);
24
+ }
25
+ return rows;
26
+ }
27
+
28
+ // Byte-identical to the hand-written sprites (tabs, single quotes, trailing newline),
29
+ // so a maintainer can drop it in and prettier won't touch it.
30
+ export function toModuleSource(art: AvatarArt): string {
31
+ const rows = art.pixels.map((row) => `\t\t'${row}'`).join(',\n');
32
+ return `import type { AvatarArt } from './types.ts';
33
+
34
+ const art: AvatarArt = {
35
+ \tname: '${art.name}',
36
+ \tpixels: [
37
+ ${rows}
38
+ \t]
39
+ };
40
+
41
+ export default art;
42
+ `;
43
+ }
44
+
45
+ // The art is ~64 chars, far below any URL length limit.
46
+ export function toIssueUrl(art: AvatarArt): string {
47
+ const title = `Avatar contribution: ${art.name}`;
48
+ const body = [
49
+ "Hi! I drew this avatar in the editor easter egg and I'd love to see it in the official set.",
50
+ '',
51
+ '```',
52
+ ...art.pixels,
53
+ '```',
54
+ '',
55
+ `Ready-to-paste module (\`src/avatars/${art.name}.ts\`, plus a line in \`src/avatars/index.ts\`):`,
56
+ '',
57
+ '```ts',
58
+ toModuleSource(art).trimEnd(),
59
+ '```',
60
+ '',
61
+ '_It should satisfy `src/avatars/avatars.test.ts`: exactly 8×8, only `#`/`.` pixels, unique name._'
62
+ ].join('\n');
63
+ const params = new URLSearchParams({ title, body });
64
+ return `${REPO_URL}/issues/new?${params}`;
65
+ }
@@ -0,0 +1,17 @@
1
+ import type { AvatarArt } from './types.ts';
2
+
3
+ const art: AvatarArt = {
4
+ name: 'skull',
5
+ pixels: [
6
+ '.######.',
7
+ '########',
8
+ '#.####.#',
9
+ '#.#..#.#',
10
+ '########',
11
+ '##.##.##',
12
+ '.#.##.#.',
13
+ '.##.##..'
14
+ ]
15
+ };
16
+
17
+ export default art;
@@ -0,0 +1,17 @@
1
+ import type { AvatarArt } from './types.ts';
2
+
3
+ const art: AvatarArt = {
4
+ name: 'snail',
5
+ pixels: [
6
+ '.####..#',
7
+ '#....#.#',
8
+ '#.##.#.#',
9
+ '#.#..#.#',
10
+ '#....##.',
11
+ '#...#.#.',
12
+ '######.#',
13
+ '.######.'
14
+ ]
15
+ };
16
+
17
+ export default art;
@@ -0,0 +1,17 @@
1
+ import type { AvatarArt } from './types.ts';
2
+
3
+ const art: AvatarArt = {
4
+ name: 'snake',
5
+ pixels: [
6
+ '...###..',
7
+ '.###..#.',
8
+ '#.#..#..',
9
+ '##..#..#',
10
+ '...#..#.',
11
+ '..#...##',
12
+ '.#.....#',
13
+ '.######.'
14
+ ]
15
+ };
16
+
17
+ export default art;
@@ -0,0 +1,17 @@
1
+ import type { AvatarArt } from './types.ts';
2
+
3
+ const art: AvatarArt = {
4
+ name: 'snakegame',
5
+ pixels: [
6
+ '########',
7
+ '#......#',
8
+ '#.##...#',
9
+ '#.#..#.#',
10
+ '#.##...#',
11
+ '#..##..#',
12
+ '#......#',
13
+ '########'
14
+ ]
15
+ };
16
+
17
+ export default art;
@@ -0,0 +1,17 @@
1
+ import type { AvatarArt } from './types.ts';
2
+
3
+ const art: AvatarArt = {
4
+ name: 'star',
5
+ pixels: [
6
+ '...##...',
7
+ '...##...',
8
+ '########',
9
+ '.######.',
10
+ '.######.',
11
+ '.##..##.',
12
+ '##....##',
13
+ '#......#'
14
+ ]
15
+ };
16
+
17
+ export default art;
@@ -0,0 +1,17 @@
1
+ import type { AvatarArt } from './types.ts';
2
+
3
+ const art: AvatarArt = {
4
+ name: 'svelte',
5
+ pixels: [
6
+ '..#####.',
7
+ '.###..#.',
8
+ '##...#..',
9
+ '########',
10
+ '########',
11
+ '..#...##',
12
+ '.#..###.',
13
+ '.####...'
14
+ ]
15
+ };
16
+
17
+ export default art;
@@ -0,0 +1,17 @@
1
+ import type { AvatarArt } from './types.ts';
2
+
3
+ const art: AvatarArt = {
4
+ name: 'target',
5
+ pixels: [
6
+ '..####..',
7
+ '.#....#.',
8
+ '#......#',
9
+ '#..##..#',
10
+ '#..##..#',
11
+ '#......#',
12
+ '.#....#.',
13
+ '..####..'
14
+ ]
15
+ };
16
+
17
+ export default art;
@@ -0,0 +1,17 @@
1
+ import type { AvatarArt } from './types.ts';
2
+
3
+ const art: AvatarArt = {
4
+ name: 'tree',
5
+ pixels: [
6
+ '...##...',
7
+ '..####..',
8
+ '.######.',
9
+ '..####..',
10
+ '.######.',
11
+ '########',
12
+ '...##...',
13
+ '...##...'
14
+ ]
15
+ };
16
+
17
+ export default art;
@@ -0,0 +1,24 @@
1
+ // The string legend keeps the art human-editable — you can eyeball a creature in the source.
2
+ //
3
+ // '#' → on (lit pixel)
4
+ // ' ' or '.' → off (unlit pixel)
5
+ export type AvatarArt = {
6
+ name: string; // also the uniqueness key
7
+ pixels: string[];
8
+ };
9
+
10
+ export const OFF = 0;
11
+ export const ON = 1;
12
+
13
+ export const ROWS = 8;
14
+ export const COLS = 8;
15
+
16
+ export function decode(art: AvatarArt): number[] {
17
+ const cells: number[] = [];
18
+ for (const row of art.pixels) {
19
+ for (const ch of row) {
20
+ cells.push(ch === '#' ? ON : OFF);
21
+ }
22
+ }
23
+ return cells;
24
+ }
@@ -0,0 +1,17 @@
1
+ import type { AvatarArt } from './types.ts';
2
+
3
+ const art: AvatarArt = {
4
+ name: 'ukraine',
5
+ pixels: [
6
+ '...##...',
7
+ '#..##..#',
8
+ '##.##.##',
9
+ '#..##..#',
10
+ '##.##.##',
11
+ '#..##..#',
12
+ '########',
13
+ '...##...'
14
+ ]
15
+ };
16
+
17
+ export default art;
@@ -0,0 +1,17 @@
1
+ import type { AvatarArt } from './types.ts';
2
+
3
+ const art: AvatarArt = {
4
+ name: 'whale',
5
+ pixels: [
6
+ '....#...',
7
+ '...###..',
8
+ '..####.#',
9
+ '.#.####.',
10
+ '######.#',
11
+ '.#####..',
12
+ '..####..',
13
+ '...##...'
14
+ ]
15
+ };
16
+
17
+ export default art;
@@ -0,0 +1,17 @@
1
+ import type { AvatarArt } from './types.ts';
2
+
3
+ const art: AvatarArt = {
4
+ name: 'wheat',
5
+ pixels: [
6
+ '........',
7
+ '....#.#.',
8
+ '...#.#..',
9
+ '..#.#.#.',
10
+ '..##.#..',
11
+ '..###...',
12
+ '.#......',
13
+ '#.......'
14
+ ]
15
+ };
16
+
17
+ export default art;
@@ -0,0 +1,17 @@
1
+ import type { AvatarArt } from './types.ts';
2
+
3
+ const art: AvatarArt = {
4
+ name: 'yinyan',
5
+ pixels: [
6
+ '.......#',
7
+ '.##...##',
8
+ '.##..###',
9
+ '....####',
10
+ '...#####',
11
+ '..###..#',
12
+ '.####..#',
13
+ '########'
14
+ ]
15
+ };
16
+
17
+ export default art;
@@ -0,0 +1,35 @@
1
+ <script lang="ts">
2
+ import type { Snippet } from 'svelte';
3
+ import House from '@lucide/svelte/icons/house';
4
+
5
+ let { children }: { children?: Snippet } = $props();
6
+ </script>
7
+
8
+ <header class="bar">
9
+ <a class="home" href="/" title="All instances" aria-label="All instances"><House size={18} /></a>
10
+ {@render children?.()}
11
+ </header>
12
+
13
+ <style>
14
+ .bar {
15
+ display: flex;
16
+ align-items: stretch;
17
+ gap: 0;
18
+ height: 44px;
19
+ border-bottom: 1px solid var(--rule);
20
+ background: var(--bg-card);
21
+ }
22
+ .home {
23
+ display: inline-flex;
24
+ align-items: center;
25
+ justify-content: center;
26
+ width: 48px;
27
+ flex: none;
28
+ color: var(--ink);
29
+ border-right: 1px solid var(--rule);
30
+ }
31
+ .home:hover {
32
+ background: var(--ink);
33
+ color: var(--bg);
34
+ }
35
+ </style>