@wenathlan/cobaia 0.0.0-stage → 2.0.158
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.
- package/App.tsx +52 -0
- package/Dockerfile +48 -0
- package/_headers +4 -0
- package/_redirects +1 -0
- package/adsconfig.ts +59 -0
- package/biome.jsonc +134 -0
- package/bun.lock +2451 -0
- package/capacitor.config.ts +51 -0
- package/checkoutlinks.ts +80 -0
- package/cli.ts +114 -0
- package/cobaia.csproj +22 -0
- package/cobaia.gemspec +14 -0
- package/cobaia.java +16 -0
- package/content.ts +425 -0
- package/db.ts +219 -0
- package/devthink.toml +5 -0
- package/docs/features.md +58 -0
- package/docs/monetization.md +61 -0
- package/familyurl.ts +22 -0
- package/favicon.svg +1 -0
- package/icon.svg +1 -0
- package/index.html +26 -0
- package/labels.ts +291 -0
- package/manifest.webmanifest +56 -0
- package/mime.types +12 -0
- package/netlify.toml +2 -0
- package/package.json +207 -4
- package/pnpm-workspace.yaml +101 -0
- package/pnpmboot.package-lock.json +157 -0
- package/pnpmboot.package.json +6 -0
- package/pom.xml +29 -0
- package/posts.ts +54 -0
- package/robots.txt +90 -0
- package/roster.ts +29 -0
- package/sandboxmodality.ts +138 -0
- package/schema.prisma +31 -0
- package/sitemap.xml +42 -0
- package/sol/Sol.tsx +91 -0
- package/sol/apps/apps.tsx +66 -0
- package/sol/blog/blog.tsx +86 -0
- package/sol/home/home.tsx +140 -0
- package/sol/intro/intro.tsx +187 -0
- package/sol/legal/legal.tsx +76 -0
- package/sol/notfound/notfound.tsx +32 -0
- package/sol/pricing/pricing.tsx +98 -0
- package/sol/shell/Shell.tsx +161 -0
- package/sol/sol.css +1951 -0
- package/sol/support/support.tsx +102 -0
- package/sol/wingets/IntroFooter.tsx +69 -0
- package/sol/wingets/IntroPlans.tsx +93 -0
- package/sol/wingets/IntroSplash.tsx +105 -0
- package/sol/wingets/ShellAdsslot.tsx +47 -0
- package/sol/wingets/ShellBrand.tsx +86 -0
- package/sol/wingets/index.ts +18 -0
- package/tests/adsconfig.test.ts +51 -0
- package/tests/checkoutlinks.test.ts +73 -0
- package/tests/familyurl.test.ts +40 -0
- package/tests/posts.test.ts +76 -0
- package/tests/sandboxmodality.test.ts +77 -0
- package/tsconfig.json +22 -0
- package/tsconfig.node.json +22 -0
- package/vercel.json +3 -0
- package/vite.config.ts +44 -0
- package/vitest.config.ts +42 -0
- package/wrangler.toml +7 -0
- package/README.md +0 -3
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
// # familyurl.test — the address book contract of the family deploy units.
|
|
2
|
+
// Run: pnpm vitest run tests/familyurl.test.ts
|
|
3
|
+
// The suite watches the promise the directory and the footer make: every
|
|
4
|
+
// family member resolves one level above this application, always with the
|
|
5
|
+
// trailing slash, and pasted segments or stray slashes land on the same
|
|
6
|
+
// address. Pure string shaping — no network, no side effects.
|
|
7
|
+
import assert from "node:assert/strict";
|
|
8
|
+
import { describe, it } from "vitest";
|
|
9
|
+
import { familyurl } from "../familyurl.ts";
|
|
10
|
+
|
|
11
|
+
describe("the familyurl contract", () => {
|
|
12
|
+
it("resolves a bare slug one level above, with the trailing slash", () => {
|
|
13
|
+
assert.equal(familyurl("vault"), "../vault/");
|
|
14
|
+
assert.equal(familyurl("devthink"), "../devthink/");
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
it("trims stray slashes from pasted segments", () => {
|
|
18
|
+
assert.equal(familyurl("/forge/"), "../forge/");
|
|
19
|
+
assert.equal(familyurl("forge/"), "../forge/");
|
|
20
|
+
assert.equal(familyurl("/forge"), "../forge/");
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
it("resolves the whole roster the same way", () => {
|
|
24
|
+
const roster = [
|
|
25
|
+
"devthink",
|
|
26
|
+
"saddle",
|
|
27
|
+
"forge",
|
|
28
|
+
"foundry",
|
|
29
|
+
"vault",
|
|
30
|
+
"getry",
|
|
31
|
+
"cadria",
|
|
32
|
+
"debonair",
|
|
33
|
+
"stealthhead",
|
|
34
|
+
"argan",
|
|
35
|
+
];
|
|
36
|
+
for (const slug of roster) {
|
|
37
|
+
assert.equal(familyurl(slug), `../${slug}/`);
|
|
38
|
+
}
|
|
39
|
+
});
|
|
40
|
+
});
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
// # posts.test — the seed blog of the family site.
|
|
2
|
+
// Run: pnpm vitest run tests/posts.test.ts
|
|
3
|
+
// The suite watches the promise the blog page makes: the index is sorted
|
|
4
|
+
// newest first no matter the array order, the slugs are unique and url-safe,
|
|
5
|
+
// every seed post carries a real ~300 word body (the ad networks approve
|
|
6
|
+
// content, not containers) and the honest word counter agrees with itself.
|
|
7
|
+
import assert from "node:assert/strict";
|
|
8
|
+
import { describe, expect, it } from "vitest";
|
|
9
|
+
import { postindex, posts, postwords } from "../posts.ts";
|
|
10
|
+
|
|
11
|
+
// the content lane answers the same rows the seed carries (wave of the
|
|
12
|
+
// content law): the const retired, the accessor serves the identical data
|
|
13
|
+
|
|
14
|
+
describe("the seed blog", () => {
|
|
15
|
+
it("carries the three seed posts about the family", () => {
|
|
16
|
+
assert.equal(posts().length, 3);
|
|
17
|
+
assert.deepEqual(
|
|
18
|
+
posts().map((post) => post.slug),
|
|
19
|
+
["ten-sites-one-engine", "one-css-one-tree", "no-backend-no-tracking"],
|
|
20
|
+
);
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
it("indexes the posts newest first", () => {
|
|
24
|
+
const index = postindex();
|
|
25
|
+
assert.deepEqual(
|
|
26
|
+
index.map((post) => post.slug),
|
|
27
|
+
["ten-sites-one-engine", "one-css-one-tree", "no-backend-no-tracking"],
|
|
28
|
+
);
|
|
29
|
+
for (let i = 1; i < index.length; i++) {
|
|
30
|
+
assert.ok(index[i - 1].date >= index[i].date, "the index must be sorted by date, newest first");
|
|
31
|
+
}
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
it("does not mutate the source order when indexing", () => {
|
|
35
|
+
const before = posts()
|
|
36
|
+
.map((post) => post.slug)
|
|
37
|
+
.join(",");
|
|
38
|
+
postindex();
|
|
39
|
+
assert.equal(
|
|
40
|
+
posts()
|
|
41
|
+
.map((post) => post.slug)
|
|
42
|
+
.join(","),
|
|
43
|
+
before,
|
|
44
|
+
);
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
it("keeps the slugs unique and url-safe", () => {
|
|
48
|
+
const slugs = posts().map((post) => post.slug);
|
|
49
|
+
assert.equal(new Set(slugs).size, slugs.length);
|
|
50
|
+
for (const slug of slugs) {
|
|
51
|
+
assert.match(slug, /^[a-z0-9]+(-[a-z0-9]+)*$/);
|
|
52
|
+
}
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
it("dates every post in iso form and before the wave", () => {
|
|
56
|
+
for (const post of posts()) {
|
|
57
|
+
assert.match(post.date, /^\d{4}-\d{2}-\d{2}$/);
|
|
58
|
+
assert.ok(post.date <= "2026-10-10", "a seed post cannot be dated in the future");
|
|
59
|
+
}
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
it("writes a real ~300 word body for every post", () => {
|
|
63
|
+
for (const post of posts()) {
|
|
64
|
+
const words = postwords(post);
|
|
65
|
+
assert.ok(words >= 250, `${post.slug} carries ${words} words — the seed posts ship real content`);
|
|
66
|
+
assert.ok(words <= 380, `${post.slug} carries ${words} words — the seed posts stay ~300`);
|
|
67
|
+
assert.ok(post.excerpt.length > 40, `${post.slug} must carry a real excerpt`);
|
|
68
|
+
assert.ok(post.body.length >= 3, `${post.slug} must carry more than two paragraphs`);
|
|
69
|
+
}
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
it("counts words the honest way (split, no empties)", () => {
|
|
73
|
+
const first = posts()[0];
|
|
74
|
+
expect(postwords(first)).toBe(first.body.join(" ").split(/\s+/).filter(Boolean).length);
|
|
75
|
+
});
|
|
76
|
+
});
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
// # sandboxmodality.test — the workload lane declaration of cobaia (wave
|
|
2
|
+
// WL1): the mirrored rows answer the engine catalog byte for byte (the
|
|
3
|
+
// lockstep pin — every lane, role, demand and honest today the engine
|
|
4
|
+
// FAMILYLANES table carries for cobaia, compared through the library
|
|
5
|
+
// bridge so the vendor can never drift in silence), every row names the
|
|
6
|
+
// app slug, and the seat law answers the deploy's opt-in (absent or blank
|
|
7
|
+
// answers the declared local default, "join" opts the lanes onto the
|
|
8
|
+
// platform's join resolver — the nuclear modality law, and a named
|
|
9
|
+
// modality id pins the seat for the platform's join to validate at
|
|
10
|
+
// dispatch — this module never judges engine vocabulary). runnable with
|
|
11
|
+
// vitest:
|
|
12
|
+
// pnpm vitest run tests/sandboxmodality.test.ts
|
|
13
|
+
import assert from "node:assert/strict";
|
|
14
|
+
import { lanesof } from "@wenathlan/saddle/workloadlaw";
|
|
15
|
+
import { describe, it } from "vitest";
|
|
16
|
+
import { APPSLUG, laneof, lanesandbox, lanesandboxfromenv, SANDBOXLANEENV, WORKLOADLANES } from "../sandboxmodality.ts";
|
|
17
|
+
|
|
18
|
+
describe("the workload lane mirror (the engine catalog lockstep)", () => {
|
|
19
|
+
it("answers the engine catalog rows for cobaia — the byte pin", () => {
|
|
20
|
+
const engine = lanesof("cobaia");
|
|
21
|
+
assert.equal(engine.length, WORKLOADLANES.length, "the mirror carries every cobaia lane");
|
|
22
|
+
for (let index = 0; index < engine.length; index += 1) {
|
|
23
|
+
const row = engine[index];
|
|
24
|
+
const mirror = WORKLOADLANES[index];
|
|
25
|
+
assert.equal(mirror.app, row.app);
|
|
26
|
+
assert.equal(mirror.lane, row.lane, `lane ${index} id drifts from the engine`);
|
|
27
|
+
assert.equal(mirror.role, row.role, `lane ${row.lane} role drifts from the engine`);
|
|
28
|
+
assert.deepEqual(mirror.demand, row.demand, `lane ${row.lane} demand drifts from the engine`);
|
|
29
|
+
assert.equal(mirror.today, row.today, `lane ${row.lane} today drifts from the engine`);
|
|
30
|
+
}
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
it("carries the app slug on every row and answers the lane lookup", () => {
|
|
34
|
+
for (const row of WORKLOADLANES) {
|
|
35
|
+
assert.equal(row.app, APPSLUG);
|
|
36
|
+
}
|
|
37
|
+
const first = laneof("plan-checkout");
|
|
38
|
+
assert.ok(first !== undefined);
|
|
39
|
+
assert.equal(first.today, "app-lane");
|
|
40
|
+
assert.equal(laneof("no-such-lane"), undefined);
|
|
41
|
+
});
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
describe("the sandbox lane seat (the deploy decides)", () => {
|
|
45
|
+
it("answers the declared local default when the deploy carries no choice", () => {
|
|
46
|
+
const absent = lanesandbox(undefined);
|
|
47
|
+
assert.deepEqual(absent, { ok: true, seat: "local", sandboxed: false });
|
|
48
|
+
const blank = lanesandbox(" ");
|
|
49
|
+
assert.deepEqual(blank, { ok: true, seat: "local", sandboxed: false });
|
|
50
|
+
const explicit = lanesandbox("local");
|
|
51
|
+
assert.deepEqual(explicit, { ok: true, seat: "local", sandboxed: false });
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
it("opts the lanes onto the platform join when the deploy chooses join", () => {
|
|
55
|
+
const joined = lanesandbox("join");
|
|
56
|
+
assert.deepEqual(joined, { ok: true, seat: "join", sandboxed: true, pinned: false });
|
|
57
|
+
const padded = lanesandbox(" join ");
|
|
58
|
+
assert.deepEqual(padded, { ok: true, seat: "join", sandboxed: true, pinned: false });
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
it("pins the named modality for the platform join to validate", () => {
|
|
62
|
+
const pinned = lanesandbox("runnernode");
|
|
63
|
+
assert.deepEqual(pinned, { ok: true, seat: "runnernode", sandboxed: true, pinned: true });
|
|
64
|
+
// the module never judges engine vocabulary: the platform's join
|
|
65
|
+
// validates the pinned id at dispatch, the mirror only names it
|
|
66
|
+
const unusual = lanesandbox("microvmfirecracker");
|
|
67
|
+
assert.deepEqual(unusual, { ok: true, seat: "microvmfirecracker", sandboxed: true, pinned: true });
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
it("reads the seat off the environment lookup the deploy pins", () => {
|
|
71
|
+
assert.equal(SANDBOXLANEENV, "COBAIA_SANDBOX_LANE");
|
|
72
|
+
const unset = lanesandboxfromenv(() => undefined);
|
|
73
|
+
assert.deepEqual(unset, { ok: true, seat: "local", sandboxed: false });
|
|
74
|
+
const set = lanesandboxfromenv((key) => (key === SANDBOXLANEENV ? "join" : undefined));
|
|
75
|
+
assert.deepEqual(set, { ok: true, seat: "join", sandboxed: true, pinned: false });
|
|
76
|
+
});
|
|
77
|
+
});
|
package/tsconfig.json
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
// the cobaia typescript baseline.
|
|
2
|
+
{
|
|
3
|
+
"compilerOptions": {
|
|
4
|
+
"target": "ES2022",
|
|
5
|
+
"noEmit": true,
|
|
6
|
+
"module": "ESNext",
|
|
7
|
+
"moduleResolution": "bundler",
|
|
8
|
+
"paths": {
|
|
9
|
+
"@wenathlan/vault/labelstore": ["../vault/labelstore.ts"],
|
|
10
|
+
"@wenathlan/vault/storagelane": ["../vault/storagelane.ts"]
|
|
11
|
+
},
|
|
12
|
+
"strict": true,
|
|
13
|
+
"lib": ["esnext", "dom", "dom.iterable"],
|
|
14
|
+
"jsx": "react-jsx",
|
|
15
|
+
"esModuleInterop": true,
|
|
16
|
+
"skipLibCheck": true,
|
|
17
|
+
"allowImportingTsExtensions": true,
|
|
18
|
+
"types": ["vite/client", "node"]
|
|
19
|
+
},
|
|
20
|
+
"include": ["*.ts", "*.tsx", "sol/**/*.ts", "sol/**/*.tsx"],
|
|
21
|
+
"exclude": ["node_modules", "dist", "**/*.test.ts"]
|
|
22
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"target": "ES2022",
|
|
4
|
+
"lib": ["ES2023"],
|
|
5
|
+
"module": "ESNext",
|
|
6
|
+
"skipLibCheck": true,
|
|
7
|
+
|
|
8
|
+
/* Bundler mode */
|
|
9
|
+
"moduleResolution": "bundler",
|
|
10
|
+
"allowImportingTsExtensions": true,
|
|
11
|
+
"isolatedModules": true,
|
|
12
|
+
"moduleDetection": "force",
|
|
13
|
+
"noEmit": true,
|
|
14
|
+
|
|
15
|
+
/* Linting */
|
|
16
|
+
"strict": true,
|
|
17
|
+
"noUnusedLocals": true,
|
|
18
|
+
"noUnusedParameters": true,
|
|
19
|
+
"noFallthroughCasesInSwitch": true
|
|
20
|
+
},
|
|
21
|
+
"include": ["vite.config.ts"]
|
|
22
|
+
}
|
package/vercel.json
ADDED
package/vite.config.ts
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/** Style: cobaia sol — the vite config lives at the app root while the theme stays in sol/: static build emitting the hashed bundles directly into the app root folder (publish = "."), with a repository-scoped base path so the theme answers any deploy root (pages subpath, vercel, netlify, workers). The Tailwind 4 vite plugin compiles the theme stylesheet's `@import "tailwindcss"` head (the @theme source of truth + the light/hcf custom variants). */
|
|
2
|
+
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
import tailwindcss from "@tailwindcss/vite";
|
|
5
|
+
import react from "@vitejs/plugin-react";
|
|
6
|
+
import { defineConfig } from "vite";
|
|
7
|
+
|
|
8
|
+
function pagesBasePath(value: string | undefined): string {
|
|
9
|
+
const candidate = value?.trim() || "/";
|
|
10
|
+
if (candidate === "." || candidate === "./") return "./";
|
|
11
|
+
return candidate === "/" ? candidate : `/${candidate.replace(/^\/+|\/+$/g, "")}/`;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export default defineConfig({
|
|
15
|
+
base: pagesBasePath(process.env.VITE_BASE_PATH),
|
|
16
|
+
plugins: [react(), tailwindcss()],
|
|
17
|
+
resolve: {
|
|
18
|
+
alias: {
|
|
19
|
+
/** the label store bridge of the ownership law: the app's copy
|
|
20
|
+
* mechanism rides the vault factory through the published library
|
|
21
|
+
* specifier ("@wenathlan/vault/labelstore"), and this bridge resolves
|
|
22
|
+
* the specifier to the monorepo source the sibling engine carries —
|
|
23
|
+
* the mechanism is never duplicated inside cobaia. the entry retires
|
|
24
|
+
* when the published envelope carries the built label store. */
|
|
25
|
+
"@wenathlan/vault/labelstore": path.resolve(import.meta.dirname, "../vault/labelstore.ts"),
|
|
26
|
+
"@": path.resolve(import.meta.dirname, "Sol"),
|
|
27
|
+
},
|
|
28
|
+
},
|
|
29
|
+
root: import.meta.dirname,
|
|
30
|
+
build: {
|
|
31
|
+
outDir: path.resolve(import.meta.dirname, "."),
|
|
32
|
+
emptyOutDir: false,
|
|
33
|
+
assetsDir: "",
|
|
34
|
+
},
|
|
35
|
+
/** the theme (sol/) and the root logics (checkoutlinks, posts, adsconfig) share one app root, so the dev server allows the app root. */
|
|
36
|
+
server: {
|
|
37
|
+
fs: {
|
|
38
|
+
allow: [import.meta.dirname, path.resolve(import.meta.dirname, "../vault")],
|
|
39
|
+
},
|
|
40
|
+
host: true,
|
|
41
|
+
strictPort: false,
|
|
42
|
+
allowedHosts: true,
|
|
43
|
+
},
|
|
44
|
+
});
|
package/vitest.config.ts
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import path from "node:path";
|
|
2
|
+
import { defineConfig } from "vitest/config";
|
|
3
|
+
|
|
4
|
+
export default defineConfig({
|
|
5
|
+
resolve: {
|
|
6
|
+
alias: {
|
|
7
|
+
/** the label store bridge of the ownership law: the app's copy
|
|
8
|
+
* mechanism rides the vault factory through the published library
|
|
9
|
+
* specifier ("@wenathlan/vault/labelstore"), and this bridge resolves
|
|
10
|
+
* the specifier to the monorepo source the sibling engine carries —
|
|
11
|
+
* the mechanism is never duplicated inside cobaia. the entry retires
|
|
12
|
+
* when the published envelope carries the built label store. */
|
|
13
|
+
"@wenathlan/vault/labelstore": path.resolve(import.meta.dirname, "../vault/labelstore.ts"),
|
|
14
|
+
|
|
15
|
+
/** the storage lane bridge of the ownership law: the app's sqlite
|
|
16
|
+
* mechanism rides the vault factory through the published library
|
|
17
|
+
* specifier ("@wenathlan/vault/storage"), and this bridge resolves
|
|
18
|
+
* the specifier to the monorepo source the sibling engine carries —
|
|
19
|
+
* the bootstrap and the helpers are never duplicated inside cobaia.
|
|
20
|
+
* the entry retires when the published envelope carries the built
|
|
21
|
+
* storage lane. */
|
|
22
|
+
"@wenathlan/vault/storage": path.resolve(import.meta.dirname, "../vault/storage.ts"),
|
|
23
|
+
|
|
24
|
+
/** the workload law bridge of the family: the app battery pins the
|
|
25
|
+
* lane mirror against the engine catalog through the published
|
|
26
|
+
* library specifier ("@wenathlan/saddle/workloadlaw"), and this
|
|
27
|
+
* bridge resolves the specifier to the monorepo source the sibling
|
|
28
|
+
* engine carries — the catalog is never duplicated inside cobaia.
|
|
29
|
+
* the entry retires when the published envelope carries the built
|
|
30
|
+
* workload law. */
|
|
31
|
+
"@wenathlan/saddle/workloadlaw": path.resolve(import.meta.dirname, "../saddle/workloadlaw.ts"),
|
|
32
|
+
},
|
|
33
|
+
},
|
|
34
|
+
test: {
|
|
35
|
+
include: ["tests/*.test.ts"],
|
|
36
|
+
environment: "node",
|
|
37
|
+
/* the timeout stays five seconds on every native runner and scales through the env the emulated arm64 container leg sets (a qemu-interpreted second answers the same green suite many times slower), so an emulated runner never fails a test a native runner passed */
|
|
38
|
+
testTimeout: Number(process.env.COBAIA_TEST_TIMEOUT_MS ?? 5000),
|
|
39
|
+
hookTimeout: Number(process.env.COBAIA_TEST_TIMEOUT_MS ?? 10000),
|
|
40
|
+
coverage: { enabled: false },
|
|
41
|
+
},
|
|
42
|
+
});
|
package/wrangler.toml
ADDED
package/README.md
DELETED