- Let Mind Builder save the things you make to your own private space.
- You’ll approve it just once — no extra password, and it’s remembered
- next time.
+ Let Mind Builder save the things you make to your own private space. You’ll approve it
+ just once — no extra password, and it’s remembered next time.
) : null}
- {error ? (
-
{error}
- ) : null}
+ {error ?
{error}
: null}
Your projects
diff --git a/src/app/layout.tsx b/src/app/layout.tsx
index 97cae9b..f997e47 100644
--- a/src/app/layout.tsx
+++ b/src/app/layout.tsx
@@ -1,7 +1,7 @@
-import type { Metadata } from "next";
-import { Fraunces, Hanken_Grotesk, JetBrains_Mono } from "next/font/google";
import { ThemeProvider } from "@mind-studio/ui";
import { mind } from "@mind-studio/ui/themes";
+import type { Metadata } from "next";
+import { Fraunces, Hanken_Grotesk, JetBrains_Mono } from "next/font/google";
import "./globals.css";
import { FeedbackLauncher } from "@/components/FeedbackLauncher";
diff --git a/src/app/login/callback/page.tsx b/src/app/login/callback/page.tsx
index 90d6697..0c1d9bb 100644
--- a/src/app/login/callback/page.tsx
+++ b/src/app/login/callback/page.tsx
@@ -1,12 +1,8 @@
"use client";
-import { useEffect } from "react";
+import { EVENTS, events, handleIncomingRedirect } from "@inrupt/solid-client-authn-browser";
import { useRouter } from "next/navigation";
-import {
- EVENTS,
- events,
- handleIncomingRedirect,
-} from "@inrupt/solid-client-authn-browser";
+import { useEffect } from "react";
export default function CallbackPage() {
const router = useRouter();
@@ -45,9 +41,5 @@ export default function CallbackPage() {
};
}, [router]);
- return (
-
- Signing you in…
-
- );
+ return Signing you in…;
}
diff --git a/src/app/page.tsx b/src/app/page.tsx
index 61e4cab..6ca6022 100644
--- a/src/app/page.tsx
+++ b/src/app/page.tsx
@@ -1,11 +1,11 @@
"use client";
-import { useEffect } from "react";
-import { useRouter } from "next/navigation";
import { MindLoginCard, writeLastIdentity } from "@mind-studio/core";
import { Badge, Card, CardContent } from "@mind-studio/ui";
+import { useRouter } from "next/navigation";
+import { useEffect } from "react";
+import { APP_NAME, oidcIssuer } from "@/lib/config";
import { useSession } from "@/lib/solid/session";
-import { oidcIssuer, APP_NAME } from "@/lib/config";
export default function HomePage() {
const { webid, loggedIn, loading, signIn } = useSession();
@@ -29,7 +29,10 @@ export default function HomePage() {
{/* ---- Hero ---- */}
-
+
Build anything, just by asking
@@ -41,8 +44,8 @@ export default function HomePage() {
- Tell us the website or app you wish you had — in your own everyday
- words. We make it real and hand you a link you can open and share.{" "}
+ Tell us the website or app you wish you had — in your own everyday words. We make it
+ real and hand you a link you can open and share.{" "}
No coding. No setup. Nothing to install.
{" "}
@@ -139,8 +142,8 @@ export default function HomePage() {
What will you make today?
- Sign in above and type your very first wish. A page for your
- business, a fun game, a tool you’ve always wanted — start anywhere.
+ Sign in above and type your very first wish. A page for your business, a fun game, a
+ tool you’ve always wanted — start anywhere.
{[
@@ -149,7 +152,11 @@ export default function HomePage() {
"a birthday invitation page",
"a tic-tac-toe game",
].map((s) => (
-
+
“{s}”
))}
@@ -194,12 +201,16 @@ function Aura() {
@@ -269,8 +280,14 @@ function AppMock() {
-
-
+
+
Building your website…
@@ -281,7 +298,9 @@ function AppMock() {
- Your website is ready 🎉
+
+ Your website is ready 🎉
+
{/* mini rendered "site" */}
diff --git a/src/components/AiSettings.tsx b/src/components/AiSettings.tsx
index e304424..6e34ca2 100644
--- a/src/components/AiSettings.tsx
+++ b/src/components/AiSettings.tsx
@@ -1,6 +1,5 @@
"use client";
-import { useCallback, useEffect, useMemo, useState } from "react";
import {
Button,
Dialog,
@@ -17,6 +16,7 @@ import {
SelectTrigger,
SelectValue,
} from "@mind-studio/ui";
+import { useCallback, useEffect, useMemo, useState } from "react";
import type {
AiCatalogEntry,
AiProviderName,
@@ -174,9 +174,8 @@ export function AiSettings({ webid }: { webid: string | null }) {
Your AI
- Mind Builder uses an AI to write your apps. The built-in one is free
- but can be slow or busy. Add your own key to build with a faster,
- smarter AI — billed to your own account.
+ Mind Builder uses an AI to write your apps. The built-in one is free but can be slow or
+ busy. Add your own key to build with a faster, smarter AI — billed to your own account.
diff --git a/src/components/Composer.tsx b/src/components/Composer.tsx
index 01ab1b9..e093d5d 100644
--- a/src/components/Composer.tsx
+++ b/src/components/Composer.tsx
@@ -1,7 +1,7 @@
"use client";
-import { useEffect, useRef, useState } from "react";
import { Button, Textarea } from "@mind-studio/ui";
+import { useEffect, useRef, useState } from "react";
const MAX_LEN = 4000;
diff --git a/src/components/Conversation.tsx b/src/components/Conversation.tsx
index aeddc07..ff14d8c 100644
--- a/src/components/Conversation.tsx
+++ b/src/components/Conversation.tsx
@@ -1,9 +1,9 @@
"use client";
-import { useEffect, useRef } from "react";
import { Avatar, AvatarFallback, Button } from "@mind-studio/ui";
-import { MessageBody } from "./MessageBody";
+import { useEffect, useRef } from "react";
import type { ChatMessage } from "@/lib/solid/chat";
+import { MessageBody } from "./MessageBody";
/** Renders the builder conversation as a friendly chat: your wishes (right),
* the builder's replies + "your app is ready" cards (left), and build-progress
@@ -62,9 +62,7 @@ function renderMessage(m: ChatMessage): React.JSX.Element {
-
- Your app is ready 🎉
-
+ Your app is ready 🎉
{m.body}
{m.previewUrl ? (
@@ -175,9 +173,7 @@ function UserAvatar({ initial }: { initial: string }): React.JSX.Element {
function Time({ iso }: { iso: string }): React.JSX.Element | null {
const t = formatTime(iso);
if (!t) return null;
- return (
- {t}
- );
+ return {t};
}
function formatTime(iso: string): string {
diff --git a/src/components/MessageBody.tsx b/src/components/MessageBody.tsx
index 1026bf6..9c42854 100644
--- a/src/components/MessageBody.tsx
+++ b/src/components/MessageBody.tsx
@@ -1,4 +1,4 @@
-import React from "react";
+import type React from "react";
/**
* Minimal, dependency-free message renderer (ported from chat):
@@ -73,7 +73,8 @@ function parseBlocks(text: string): Block[] {
return out;
}
-const INLINE_RE = /(`[^`]+`)|(\*\*\*[^*]+\*\*\*)|(\*\*[^*]+\*\*)|(__[^_]+__)|(\*[^*\s](?:[^*]*[^*\s])?\*)|((?"]+[^\s<>".,;:!?)\]])/g;
+const INLINE_RE =
+ /(`[^`]+`)|(\*\*\*[^*]+\*\*\*)|(\*\*[^*]+\*\*)|(__[^_]+__)|(\*[^*\s](?:[^*]*[^*\s])?\*)|((?"]+[^\s<>".,;:!?)\]])/g;
function renderInline(text: string): React.ReactNode[] {
const out: React.ReactNode[] = [];
diff --git a/src/components/PreviewPane.tsx b/src/components/PreviewPane.tsx
index 027b516..f161c96 100644
--- a/src/components/PreviewPane.tsx
+++ b/src/components/PreviewPane.tsx
@@ -1,7 +1,7 @@
"use client";
-import { useState } from "react";
import { Button } from "@mind-studio/ui";
+import { useState } from "react";
import type { ProjectStatus } from "@/lib/builder/types";
/** Right-hand live preview: an iframe of the published site, or a friendly
@@ -27,9 +27,7 @@ export function PreviewPane({
// Cache-bust so the browser re-fetches index.html (its hashed asset refs
// change every build) on both auto (publish) and manual reloads.
const version = reloadNonce + manualReload;
- const src = pagesUrl
- ? `${pagesUrl}${pagesUrl.includes("?") ? "&" : "?"}v=${version}`
- : null;
+ const src = pagesUrl ? `${pagesUrl}${pagesUrl.includes("?") ? "&" : "?"}v=${version}` : null;
return (
diff --git a/src/lib/builder/bridge-client.ts b/src/lib/builder/bridge-client.ts
index a8eda94..11b4438 100644
--- a/src/lib/builder/bridge-client.ts
+++ b/src/lib/builder/bridge-client.ts
@@ -125,10 +125,7 @@ export async function createRepo(
return call(webId, "/api/repos", { method: "POST", body: args });
}
-export async function getRepo(
- owner: string,
- name: string,
-): Promise<{ repo: BridgeRepo } | null> {
+export async function getRepo(owner: string, name: string): Promise<{ repo: BridgeRepo } | null> {
try {
return await call(null, `/api/repos/${owner}/${name}`);
} catch (e) {
@@ -149,10 +146,7 @@ export async function enablePages(
});
}
-export async function getPages(
- owner: string,
- name: string,
-): Promise<{ pages: BridgePages }> {
+export async function getPages(owner: string, name: string): Promise<{ pages: BridgePages }> {
return call(null, `/api/repos/${owner}/${name}/pages`);
}
@@ -322,10 +316,7 @@ export async function setAiKey(
});
}
-export async function deleteAiKey(
- webId: string,
- provider: string,
-): Promise<{ ok: boolean }> {
+export async function deleteAiKey(webId: string, provider: string): Promise<{ ok: boolean }> {
return call(webId, `/api/profile/ai/keys/${provider}`, { method: "DELETE" });
}
@@ -341,9 +332,7 @@ export async function setAiPref(
}
/** Whether the bridge holds a delegated pod-write grant for this WebID. */
-export async function getConnection(
- webId: string,
-): Promise<{ connected: boolean }> {
+export async function getConnection(webId: string): Promise<{ connected: boolean }> {
return call(null, `/api/identities/${encodeURIComponent(webId)}`);
}
diff --git a/src/lib/builder/conversation-client.ts b/src/lib/builder/conversation-client.ts
index a3c43ff..9948638 100644
--- a/src/lib/builder/conversation-client.ts
+++ b/src/lib/builder/conversation-client.ts
@@ -1,11 +1,7 @@
"use client";
-import {
- ensureRoom,
- postMessage,
- type AuthenticatedFetch,
-} from "@/lib/solid/chat";
-import { projectRoomUrl, podRootFromWebId } from "@/lib/solid/pod";
+import { type AuthenticatedFetch, ensureRoom, postMessage } from "@/lib/solid/chat";
+import { podRootFromWebId, projectRoomUrl } from "@/lib/solid/pod";
import type { MessageKind } from "./types";
/** foaf:maker IRI for builder-authored (status / preview / question) messages. */
diff --git a/src/lib/builder/db.ts b/src/lib/builder/db.ts
index c005e79..e799abd 100644
--- a/src/lib/builder/db.ts
+++ b/src/lib/builder/db.ts
@@ -1,8 +1,8 @@
-import Database from "better-sqlite3";
import { mkdirSync, readFileSync } from "node:fs";
import { tmpdir } from "node:os";
import { dirname, join } from "node:path";
import { fileURLToPath } from "node:url";
+import Database from "better-sqlite3";
import { indexerDataDir } from "@/lib/env";
import type { Project, ProjectStatus } from "./types";
@@ -26,9 +26,7 @@ function openAt(dir: string): Database.Database {
// Tiny forward-migration for the non-authoritative cache: add columns that
// postdate an existing builder.db (CREATE TABLE IF NOT EXISTS won't add them).
try {
- db.exec(
- "ALTER TABLE project_progress ADD COLUMN last_agent_run_id INTEGER NOT NULL DEFAULT 0",
- );
+ db.exec("ALTER TABLE project_progress ADD COLUMN last_agent_run_id INTEGER NOT NULL DEFAULT 0");
} catch {
// column already exists — fine
}
@@ -90,9 +88,9 @@ function toProject(row: ProjectRow): Project {
}
export function getProject(slug: string): Project | null {
- const row = getDb()
- .prepare("SELECT * FROM projects WHERE slug = ?")
- .get(slug) as ProjectRow | undefined;
+ const row = getDb().prepare("SELECT * FROM projects WHERE slug = ?").get(slug) as
+ | ProjectRow
+ | undefined;
return row ? toProject(row) : null;
}
@@ -133,9 +131,7 @@ export function setStatus(
updatedAt: number,
): void {
getDb()
- .prepare(
- "UPDATE projects SET status = ?, status_detail = ?, updated_at = ? WHERE slug = ?",
- )
+ .prepare("UPDATE projects SET status = ?, status_detail = ?, updated_at = ? WHERE slug = ?")
.run(status, statusDetail, updatedAt, slug);
}
@@ -162,9 +158,9 @@ type ProgressRow = {
};
export function getProgress(slug: string): Progress {
- const row = getDb()
- .prepare("SELECT * FROM project_progress WHERE slug = ?")
- .get(slug) as ProgressRow | undefined;
+ const row = getDb().prepare("SELECT * FROM project_progress WHERE slug = ?").get(slug) as
+ | ProgressRow
+ | undefined;
if (!row) {
return {
slug,
diff --git a/src/lib/builder/orchestrator.ts b/src/lib/builder/orchestrator.ts
index ee79450..be74f8d 100644
--- a/src/lib/builder/orchestrator.ts
+++ b/src/lib/builder/orchestrator.ts
@@ -1,39 +1,32 @@
import "server-only";
+import { bridgeUrl } from "@/lib/env";
+import {
+ ownerFromWebId,
+ podRootFromWebId,
+ previewUrlFor,
+ projectTargetContainer,
+} from "@/lib/solid/pod";
+import { log } from "@/lib/util/log";
+import { shortSuffix, slugifyWish } from "@/lib/util/slug";
import {
+ addComment,
+ BridgeError,
+ createIssue,
createRepo,
- getRepo,
enablePages,
- mintToken,
- createIssue,
- addComment,
getIssue,
+ getRepo,
+ isPublished,
+ listIssueAgentRuns,
listPulls,
- mergePull,
listRuns,
- listIssueAgentRuns,
- isPublished,
- BridgeError,
+ mergePull,
+ mintToken,
} from "./bridge-client";
+import { getProgress, getProject, setProgress, setStatus, slugExists, upsertProject } from "./db";
+import { buildAppTitle, buildIssueBody, buildIssueTitle } from "./prompt";
import { pushScaffold } from "./scaffold";
-import {
- getProject,
- upsertProject,
- setStatus,
- getProgress,
- setProgress,
- slugExists,
-} from "./db";
-import { buildIssueBody, buildIssueTitle, buildAppTitle } from "./prompt";
-import { slugifyWish, shortSuffix } from "@/lib/util/slug";
-import { bridgeUrl } from "@/lib/env";
-import {
- ownerFromWebId,
- podRootFromWebId,
- projectTargetContainer,
- previewUrlFor,
-} from "@/lib/solid/pod";
-import { STATUS_LABELS, type MessageKind, type Project, type ProjectStatus } from "./types";
-import { log } from "@/lib/util/log";
+import { type MessageKind, type Project, type ProjectStatus, STATUS_LABELS } from "./types";
/** An event the server observed that the browser should persist to pod chat. */
export type BuilderEvent = { kind: MessageKind; body: string; previewUrl?: string };
@@ -157,7 +150,10 @@ export async function iterateProject(
const { issue } = await getIssue(project.repoOwner, project.repoName, project.lastIssue);
issueOpen = issue.status === "open";
} catch (e) {
- log.warn({ event: "builder.iterate.issue-read-failed", slug, err: String(e) }, "issue read failed");
+ log.warn(
+ { event: "builder.iterate.issue-read-failed", slug, err: String(e) },
+ "issue read failed",
+ );
}
if (!issueOpen) {
@@ -188,12 +184,19 @@ export async function iterateProject(
}
// Current task still in flight → continue the same thread.
- await addComment(webId, project.repoOwner, project.repoName, project.lastIssue, buildIssueBody(wish, true));
+ await addComment(
+ webId,
+ project.repoOwner,
+ project.repoName,
+ project.lastIssue,
+ buildIssueBody(wish, true),
+ );
setStatus(slug, "coder-running", STATUS_LABELS["coder-running"], now());
return {
project: { ...project, status: "coder-running", statusDetail: STATUS_LABELS["coder-running"] },
status: "coder-running",
- statusBody: "👍 Got it — I’m updating your app with that change. Watch here for the new preview.",
+ statusBody:
+ "👍 Got it — I’m updating your app with that change. Watch here for the new preview.",
};
}
@@ -236,7 +239,10 @@ export async function reconcile(
const openForIssue = pulls.filter((p) => p.issueId === issue.id);
for (const p of openForIssue) {
try {
- events.push({ kind: "status", body: "🎨 A new version is done — adding it to your app and building it…" });
+ events.push({
+ kind: "status",
+ body: "🎨 A new version is done — adding it to your app and building it…",
+ });
await mergePull(webId, owner, name, p.number);
// The bridge's merge writes `main` via a push that fires the
// post-receive hook, which runs `.mind/workflow.yml` (vite build) and
@@ -247,12 +253,18 @@ export async function reconcile(
status = "building";
} catch (e) {
const msg = e instanceof BridgeError ? e.message : String(e);
- events.push({ kind: "status", body: `Couldn’t merge automatically (${msg}). You may need to rephrase or retry.` });
+ events.push({
+ kind: "status",
+ body: `Couldn’t merge automatically (${msg}). You may need to rephrase or retry.`,
+ });
status = "error";
}
}
} catch (e) {
- log.warn({ event: "builder.reconcile.issue-failed", slug, err: String(e) }, "issue read failed");
+ log.warn(
+ { event: "builder.reconcile.issue-failed", slug, err: String(e) },
+ "issue read failed",
+ );
}
// 3. Workflow builds that finished since last poll → preview card / error.
@@ -282,9 +294,10 @@ export async function reconcile(
// "building" means we already merged the agent's PR, so this
// publish is the real version — even if it's the FIRST successful
// publish (the scaffold build may have failed and never published).
- body: progress.lastPublished || status === "building"
- ? "✅ Your app is ready — updated with your latest wish!"
- : "✨ A starter preview of your app is up while I code your wish. The real version will replace it shortly.",
+ body:
+ progress.lastPublished || status === "building"
+ ? "✅ Your app is ready — updated with your latest wish!"
+ : "✨ A starter preview of your app is up while I code your wish. The real version will replace it shortly.",
previewUrl: project.pagesUrl,
});
progress.lastPublished = true;
@@ -295,7 +308,11 @@ export async function reconcile(
// The most common "build failed" in practice is actually a publish
// failure: the bridge has no delegated write access to this user's
// pod. Detect it and point them at the bridge's /connect flow.
- if (/delegated identity|seeded fallback|reauthor|OwnerFetchUnavailable|needs-reauthor/i.test(em)) {
+ if (
+ /delegated identity|seeded fallback|reauthor|OwnerFetchUnavailable|needs-reauthor/i.test(
+ em,
+ )
+ ) {
events.push({
kind: "status",
body: `Your app was built, but it can’t be added to your own private space yet. Open ${bridgeUrl}/connect, sign in, and allow access — then send your wish again.`,
@@ -347,15 +364,18 @@ export async function reconcile(
// Only consider runs that have FINISHED. A run first seen while still
// "running" must not advance the watermark, or its later error is never
// surfaced and the UI hangs on "working…" forever.
- const fresh = runs.filter(
- (rr) => rr.id > progress.lastAgentRunId && rr.status !== "running",
- );
+ const fresh = runs.filter((rr) => rr.id > progress.lastAgentRunId && rr.status !== "running");
if (fresh.length) {
progress.lastAgentRunId = Math.max(progress.lastAgentRunId, ...fresh.map((rr) => rr.id));
// Only surface a failure if nothing good happened this round (no merge,
// no published preview) — a successful run already produced a PR/comment.
const errored = fresh.find((rr) => rr.status === "error");
- if (errored && status !== "published" && status !== "building" && status !== "awaiting-user") {
+ if (
+ errored &&
+ status !== "published" &&
+ status !== "building" &&
+ status !== "awaiting-user"
+ ) {
const timedOut = /exit 124|timed out|timeout/i.test(errored.summary ?? "");
// "no provider configured" = the bridge has no AI key for this user —
// an operator/setup problem, not something rephrasing can fix.
@@ -374,7 +394,10 @@ export async function reconcile(
}
}
} catch (e) {
- log.warn({ event: "builder.reconcile.agentruns-failed", slug, err: String(e) }, "agent-runs read failed");
+ log.warn(
+ { event: "builder.reconcile.agentruns-failed", slug, err: String(e) },
+ "agent-runs read failed",
+ );
}
setProgress(progress);
diff --git a/src/lib/config.ts b/src/lib/config.ts
index e7b9418..f517a9b 100644
--- a/src/lib/config.ts
+++ b/src/lib/config.ts
@@ -2,7 +2,7 @@
* Client-facing runtime config re-exported from env.ts for ergonomic imports
* in "use client" components (mirrors the chat config shape).
*/
-export { oidcIssuer, bridgeUrl, podBaseUrl } from "@/lib/env";
+export { bridgeUrl, oidcIssuer, podBaseUrl } from "@/lib/env";
import { podBaseUrl as POD_BASE } from "@/lib/env";
diff --git a/src/lib/env.ts b/src/lib/env.ts
index 36e3c34..46c2735 100644
--- a/src/lib/env.ts
+++ b/src/lib/env.ts
@@ -34,11 +34,9 @@ export const bridgeMode: BridgeMode =
// server authenticates to the bridge as the requesting WebID via
// X-Mind-Service-Secret + X-Mind-On-Behalf-Of — the production path (the dev
// X-Mind-Dev-WebId header is ignored by a prod bridge). Server-only.
-export const bridgeServiceSecret =
- process.env.BUILDER_BRIDGE_SERVICE_SECRET?.trim() || null;
+export const bridgeServiceSecret = process.env.BUILDER_BRIDGE_SERVICE_SECRET?.trim() || null;
-export const indexerDataDir =
- process.env.INDEXER_DATA_DIR ?? "./.builder-data";
+export const indexerDataDir = process.env.INDEXER_DATA_DIR ?? "./.builder-data";
function trimSlash(url: string): string {
return url.endsWith("/") ? url.slice(0, -1) : url;
diff --git a/src/lib/solid/chat-subscription.ts b/src/lib/solid/chat-subscription.ts
index c002f9f..d9714b3 100644
--- a/src/lib/solid/chat-subscription.ts
+++ b/src/lib/solid/chat-subscription.ts
@@ -1,7 +1,7 @@
"use client";
-import { dayFileUrl, ensureTodayFile, type AuthenticatedFetch } from "./chat";
import { log } from "@/lib/util/log";
+import { type AuthenticatedFetch, dayFileUrl, ensureTodayFile } from "./chat";
export type SubscriptionState = "connecting" | "connected" | "polling" | "error";
export type SubscriptionHandle = { disconnect: () => void };
@@ -29,14 +29,11 @@ async function discoverSubscriptionEndpoint(
if (!descRes.ok) return fallback;
const desc = (await descRes.json()) as Array>;
for (const node of desc) {
- const channelType = (node[
- "http://www.w3.org/ns/solid/notifications#channelType"
- ] ?? []) as Array<{ "@id"?: string }>;
+ const channelType = (node["http://www.w3.org/ns/solid/notifications#channelType"] ??
+ []) as Array<{ "@id"?: string }>;
if (
channelType.some(
- (c) =>
- c["@id"] ===
- "http://www.w3.org/ns/solid/notifications#WebSocketChannel2023",
+ (c) => c["@id"] === "http://www.w3.org/ns/solid/notifications#WebSocketChannel2023",
)
) {
const id = node["@id"];
diff --git a/src/lib/solid/chat.ts b/src/lib/solid/chat.ts
index 897b233..66a3a29 100644
--- a/src/lib/solid/chat.ts
+++ b/src/lib/solid/chat.ts
@@ -9,12 +9,12 @@ import {
getThing,
getThingAll,
getUrl,
+ type SolidDataset,
saveSolidDatasetAt,
setThing,
- type SolidDataset,
} from "@inrupt/solid-client";
-import { ulid } from "@/lib/util/ulid";
import type { MessageKind } from "@/lib/builder/types";
+import { ulid } from "@/lib/util/ulid";
// SolidOS long-chat vocabulary (interop with the SolidOS chat-pane), plus a
// small `mind:` extension to type builder status / preview-card messages
@@ -98,10 +98,7 @@ export async function ensureRoom(
}
/** Idempotently create today's empty day file (required before subscribing). */
-export async function ensureTodayFile(
- roomUrl: string,
- fetch: AuthenticatedFetch,
-): Promise {
+export async function ensureTodayFile(roomUrl: string, fetch: AuthenticatedFetch): Promise {
const dayUrl = dayFileUrl(roomUrl);
try {
await getSolidDataset(dayUrl, { fetch });
diff --git a/src/lib/solid/session.ts b/src/lib/solid/session.ts
index 413f195..664ee04 100644
--- a/src/lib/solid/session.ts
+++ b/src/lib/solid/session.ts
@@ -1,6 +1,5 @@
"use client";
-import { useEffect, useState } from "react";
import {
getDefaultSession,
handleIncomingRedirect,
@@ -8,6 +7,7 @@ import {
logout,
type Session,
} from "@inrupt/solid-client-authn-browser";
+import { useEffect, useState } from "react";
const APP_NAME = "Mind Builder";
@@ -50,8 +50,7 @@ export function useSession(): {
async function signIn(issuer: string) {
await login({
oidcIssuer: issuer,
- redirectUrl:
- typeof window !== "undefined" ? `${window.location.origin}/login/callback` : "",
+ redirectUrl: typeof window !== "undefined" ? `${window.location.origin}/login/callback` : "",
clientName: APP_NAME,
});
}
diff --git a/src/lib/util/slug.ts b/src/lib/util/slug.ts
index 29ecb45..34537ff 100644
--- a/src/lib/util/slug.ts
+++ b/src/lib/util/slug.ts
@@ -26,14 +26,22 @@ export function slugifyWish(text: string): string {
*/
export function humanizeSlug(slug: string): string {
const STOP = new Set([
- "build", "me", "a", "an", "the", "create", "make", "my", "please", "app", "some",
+ "build",
+ "me",
+ "a",
+ "an",
+ "the",
+ "create",
+ "make",
+ "my",
+ "please",
+ "app",
+ "some",
]);
let words = slug.split("-").filter(Boolean);
while (words.length > 1 && STOP.has(words[0] ?? "")) words = words.slice(1);
if (words.length === 0) words = slug.split("-").filter(Boolean);
- const title = words
- .map((w) => w.charAt(0).toUpperCase() + w.slice(1))
- .join(" ");
+ const title = words.map((w) => w.charAt(0).toUpperCase() + w.slice(1)).join(" ");
return title || slug;
}
diff --git a/tsconfig.json b/tsconfig.json
index 241ad94..cf44a1f 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -1,11 +1,7 @@
{
"compilerOptions": {
"target": "ES2020",
- "lib": [
- "dom",
- "dom.iterable",
- "esnext"
- ],
+ "lib": ["dom", "dom.iterable", "esnext"],
"allowJs": true,
"skipLibCheck": true,
"strict": true,
@@ -24,9 +20,7 @@
}
],
"paths": {
- "@/*": [
- "./src/*"
- ]
+ "@/*": ["./src/*"]
}
},
"include": [
@@ -36,7 +30,5 @@
".next/types/**/*.ts",
".next/dev/types/**/*.ts"
],
- "exclude": [
- "node_modules"
- ]
+ "exclude": ["node_modules"]
}