@somewhere-cloud/cli 0.38.0 → 0.38.1
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/dist/lib/init-agent-guide.js +20 -22
- package/dist/lib/init-agent-guide.js.map +1 -1
- package/dist/lib/init-green-template.js +11 -5
- package/dist/lib/init-green-template.js.map +1 -1
- package/dist/lib/skills-pack.generated.js +6 -6
- package/dist/lib/skills-pack.generated.js.map +1 -1
- package/npm-shrinkwrap.json +2 -2
- package/package.json +1 -1
|
@@ -4,39 +4,35 @@ import { SKILLS_DIR, skillNames } from './skills-pack.js';
|
|
|
4
4
|
// docs lint byte-compares this value when SOMEWHERE_CLI_REPO points here.
|
|
5
5
|
export const AGENT_WORKFLOW = `## Getting started — build, deploy, verify
|
|
6
6
|
|
|
7
|
-
\`somewhere init --name <slug>\`
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
7
|
+
\`somewhere init --name <slug>\` writes React + TypeScript. Signed out: local only;
|
|
8
|
+
signed in: also creates and links a project.
|
|
9
|
+
Default: sign-in UI; minimal: SDK/auth route; bare: neither. \`init --catalog --json\`: modules.
|
|
10
|
+
\`npx @somewhere-cloud/cli deploy\` publishes raw source: signed out, a temporary URL, claim URL
|
|
11
|
+
and expiry; linked, your account project. On a hosted VM, \`somewhere login\` uses browser approval and keeps you signed in.
|
|
12
|
+
Account operations, test inbox and cron need login.
|
|
12
13
|
Start auth/data/cron with \`somewhere docs recipe-signed-in-app --full\`.
|
|
13
14
|
|
|
14
15
|
After edits: \`somewhere typecheck\` and focused local/browser tests. Publish:
|
|
15
16
|
1. \`somewhere deploy\` (do not build first). Deploy
|
|
16
|
-
checks compilation, schema and secrets
|
|
17
|
-
before going live; \`somewhere deploy-check\` runs them without publishing
|
|
17
|
+
checks compilation, schema and secrets; \`somewhere deploy-check\` runs them without publishing
|
|
18
18
|
(diagnosis, review, \`--run /api/x\`).
|
|
19
|
-
2. Run \`somewhere verify\`
|
|
20
|
-
\`--flow flow.json\`); rerun after fixes. Sign test users up
|
|
19
|
+
2. Run \`somewhere verify\` on the final journey (\`--flow flow.json\`); rerun after fixes. Sign test users up
|
|
21
20
|
in-app at \`*.test.somewhere.site\`; more: \`actors\` + \`journey\` (\`somewhere docs browser\`).
|
|
22
|
-
3. \`somewhere browser
|
|
23
|
-
\`somewhere errors\`: read the failure first.
|
|
21
|
+
3. Inspect: \`somewhere browser\`; diagnose: \`somewhere logs --tail 10\`, \`somewhere errors\`.
|
|
24
22
|
4. Test mail: \`somewhere email test-inbox <addr>\` includes \`verification_code\`.
|
|
25
23
|
Don't retest sign-in or \`sw.db.from\` scoping; test each table's scope, auth before \`sw.db.server\`/raw SQL, bad input and journeys.
|
|
26
24
|
|
|
27
|
-
Routes: \`index.html\` loads \`src/main.tsx\`;
|
|
28
|
-
(\`/signin\`)
|
|
25
|
+
Routes: \`index.html\` loads \`src/main.tsx\`; unmatched extensionless paths
|
|
26
|
+
(\`/signin\`) serve it. Route the app by \`location.pathname\`.
|
|
29
27
|
\`api/notes/[id].ts\` is \`/api/notes/:id\`; \`_\`-prefixed names are import-only
|
|
30
|
-
helpers. Avoid names differing only in
|
|
28
|
+
helpers. Avoid names differing only in case.
|
|
31
29
|
|
|
32
30
|
With auth enabled, \`api/auth/[...path].ts\` is
|
|
33
31
|
\`export { somewhereAuth as default } from '@somewhere-cloud/sdk/server'\`; pages
|
|
34
|
-
use \`createSomewhereAuth()\` from \`@somewhere-cloud/sdk/auth\` (
|
|
35
|
-
\`docs
|
|
32
|
+
use \`createSomewhereAuth()\` from \`@somewhere-cloud/sdk/auth\` (client and React hooks:
|
|
33
|
+
\`somewhere docs auth-client --section react-auth-state\`). \`auth.signUp({ email, password,
|
|
36
34
|
displayName? })\` / \`auth.signIn({ email, password })\` return the user or throw
|
|
37
|
-
with the message. Gate
|
|
38
|
-
\`useAuthState()\`) as the auth starter's \`src/App.tsx\` does. Sign-up signs the user
|
|
39
|
-
in with \`email_verified: false\`; unverified users can sign in and pass
|
|
35
|
+
with the message. Gate on \`auth.getState().status\` (React: \`useAuthState()\`). Sign-up sets \`email_verified: false\`; unverified users pass
|
|
40
36
|
\`auth: 'required'\`. \`sw.auth.requireUser(req)\` returns \`{ id, email,
|
|
41
37
|
role, email_verified, … }\` or throws 401 \`AUTH_REQUIRED\`;
|
|
42
38
|
\`sw.auth.fromRequest(req)\` returns it or \`null\`.
|
|
@@ -47,10 +43,13 @@ async ({ body, user, params }, sw) => value })\`; set \`auth\` (\`'required'\`,
|
|
|
47
43
|
function (req, sw)\` returning a \`Response\`. Params: \`params.id\` there,
|
|
48
44
|
\`sw.params.id\` bare; \`somewhere typecheck\` types bare handlers too.
|
|
49
45
|
|
|
50
|
-
Data:
|
|
46
|
+
Data: \`id()\` is a random text key; use \`text()\` for references to it.
|
|
47
|
+
Declare tables in \`db/schema.ts\`; pages use \`somewhere:data\`
|
|
51
48
|
(\`data.notes.list()\`, \`.create()\`, \`.update(id, …)\`) without API files.
|
|
52
49
|
Use \`owner()\` for personal rows, \`group()\` for invited teams, \`appRole()\`
|
|
53
50
|
for app-wide roles, \`anyOf()\` for owner or a role, \`allOf()\` for members-only rows.
|
|
51
|
+
Booking/help desk: \`somewhere docs sw.db --section provider-or-booker-and-owner-or-staff-recipes\`.
|
|
52
|
+
Keep fitting scopes when an exceptional write needs \`sw.db.server.tx\`.
|
|
54
53
|
\`shared()\` gives signed-in reads and creator-only writes. \`client\` sets browser
|
|
55
54
|
columns; \`publicRead: { where }\` admits visitors. Public-profile enquiries use
|
|
56
55
|
\`client.intake\` (\`somewhere docs declared-data\`). Keep scopes and grants;
|
|
@@ -68,8 +67,7 @@ await sw.db.server.insert('entries', { user_id: profile.user_id, owner_email: pr
|
|
|
68
67
|
title: title.trim(), from_email, created_ms: Date.now() });
|
|
69
68
|
\`\`\`
|
|
70
69
|
|
|
71
|
-
|
|
72
|
-
owner. Rate limits and the alert are in \`somewhere docs recipe-signed-in-app\`.
|
|
70
|
+
Use the looked-up owner, never the body. Rate limits/alerts: \`recipe-signed-in-app\`.
|
|
73
71
|
Use \`serverOnly()\` only when every operation needs a function's own access check.
|
|
74
72
|
Structured queries: \`sw.db.from\` / \`insert\` / \`update\` / \`remove\` return \`{ data: rows[], count,
|
|
75
73
|
changes }\`; \`where: { a: 1, b: { in: ids }, c: { gte: 2 }, d: null }\` (one
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"init-agent-guide.js","sourceRoot":"","sources":["../../src/lib/init-agent-guide.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AACjE,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAE1D,2EAA2E;AAC3E,0EAA0E;AAC1E,MAAM,CAAC,MAAM,cAAc,GAAG
|
|
1
|
+
{"version":3,"file":"init-agent-guide.js","sourceRoot":"","sources":["../../src/lib/init-agent-guide.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AACjE,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAE1D,2EAA2E;AAC3E,0EAA0E;AAC1E,MAAM,CAAC,MAAM,cAAc,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA4E7B,CAAC;AAEF,MAAM,CAAC,MAAM,cAAc,GAAG,aAAa,UAAU,QAAQ;MACzD,UAAU,CAAC,mBAAmB,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,KAAK,IAAI,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC;MACvE,oJAAoJ,CAAC;AAEzJ,MAAM,CAAC,MAAM,cAAc,GAAG,uCAAuC,cAAc,KAAK,cAAc,IAAI,CAAC;AAC3G,MAAM,CAAC,MAAM,cAAc,GAAG,4CAA4C,CAAC"}
|
|
@@ -127,11 +127,17 @@ the greeting message; add caller authorization before serving private data.
|
|
|
127
127
|
The SDK and \`api/auth/[...path].ts\` are included; add your sign-in UI or use
|
|
128
128
|
\`somewhere init --template auth\` for the complete sign-in screens.
|
|
129
129
|
|
|
130
|
-
When replacing the greeting, remove its page/service files
|
|
131
|
-
|
|
132
|
-
\`removedTable\` from \`somewhere/db\`)
|
|
133
|
-
30-day retention
|
|
134
|
-
\`types/app.ts\` too. A missing optional include directory is harmless.
|
|
130
|
+
When replacing the greeting, remove its page/service files. If this table has
|
|
131
|
+
never been deployed, delete its schema declaration. If it has been deployed,
|
|
132
|
+
use \`greetings: removedTable()\` (import \`removedTable\` from \`somewhere/db\`);
|
|
133
|
+
the deploy retires it with 30-day retention, even if it is empty. Remove an
|
|
134
|
+
unused \`types/app.ts\` too. A missing optional include directory is harmless.
|
|
135
|
+
|
|
136
|
+
The greeting's \`serverOnly()\` scope demonstrates a trusted public endpoint;
|
|
137
|
+
it is not the default for your app's data. Choose fitting declared access
|
|
138
|
+
before the first deploy: \`owner()\` for personal rows, \`group()\` for teams,
|
|
139
|
+
and \`anyOf()\` for combined access. Read \`somewhere docs sw.db --section
|
|
140
|
+
provider-or-booker-and-owner-or-staff-recipes\` for booking and help-desk rules.
|
|
135
141
|
|
|
136
142
|
\`\`\`sh
|
|
137
143
|
somewhere typecheck
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"init-green-template.js","sourceRoot":"","sources":["../../src/lib/init-green-template.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAEvE,MAAM,YAAY,GAAG;;;;;;;;;;;;;;;;;;;;;CAqBpB,CAAC;AAEF,MAAM,QAAQ,GAAG;;;;;;;;;;;;;;CAchB,CAAC;AAEF,MAAM,SAAS,GAAG;;;CAGjB,CAAC;AAEF,MAAM,MAAM,GAAG;;;;;;;;;;CAUd,CAAC;AAEF,MAAM,GAAG,GAAG;;;;;;;;CAQX,CAAC;AAEF,MAAM,OAAO,GAAG;;;;;;;CAOf,CAAC;AAEF,MAAM,GAAG,GAAG;;;;;;;;;;;;;;;;;;;;;;;CAuBX,CAAC;AAEF,MAAM,IAAI,GAAG;;;;;;;;;;CAUZ,CAAC;AAEF,MAAM,MAAM,GAAG;;;;;;;;;;;;;;CAcd,CAAC;AAEF,MAAM,MAAM,GAAG
|
|
1
|
+
{"version":3,"file":"init-green-template.js","sourceRoot":"","sources":["../../src/lib/init-green-template.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAEvE,MAAM,YAAY,GAAG;;;;;;;;;;;;;;;;;;;;;CAqBpB,CAAC;AAEF,MAAM,QAAQ,GAAG;;;;;;;;;;;;;;CAchB,CAAC;AAEF,MAAM,SAAS,GAAG;;;CAGjB,CAAC;AAEF,MAAM,MAAM,GAAG;;;;;;;;;;CAUd,CAAC;AAEF,MAAM,GAAG,GAAG;;;;;;;;CAQX,CAAC;AAEF,MAAM,OAAO,GAAG;;;;;;;CAOf,CAAC;AAEF,MAAM,GAAG,GAAG;;;;;;;;;;;;;;;;;;;;;;;CAuBX,CAAC;AAEF,MAAM,IAAI,GAAG;;;;;;;;;;CAUZ,CAAC;AAEF,MAAM,MAAM,GAAG;;;;;;;;;;;;;;CAcd,CAAC;AAEF,MAAM,MAAM,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA8Bd,CAAC;AAEF,MAAM,UAAU,mBAAmB;IACjC,OAAO;QACL,EAAE,IAAI,EAAE,YAAY,EAAE,OAAO,EAAE,yJAAyJ,EAAE;QAC1L,EAAE,IAAI,EAAE,WAAW,EAAE,OAAO,EAAE,cAAc,EAAE;QAC9C,EAAE,IAAI,EAAE,WAAW,EAAE,OAAO,EAAE,cAAc,EAAE;QAC9C,EAAE,IAAI,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,EAAE;QACtC,EAAE,IAAI,EAAE,cAAc,EAAE,OAAO,EAAE,YAAY,EAAE;QAC/C,EAAE,IAAI,EAAE,eAAe,EAAE,OAAO,EAAE,QAAQ,EAAE;QAC5C;YACE,IAAI,EAAE,YAAY;YAClB,OAAO,EAAE,oUAAoU;SAC9U;QACD,EAAE,IAAI,EAAE,aAAa,EAAE,OAAO,EAAE,GAAG,EAAE;QACrC,EAAE,IAAI,EAAE,cAAc,EAAE,OAAO,EAAE,IAAI,EAAE;QACvC,EAAE,IAAI,EAAE,0BAA0B,EAAE,OAAO,EAAE,OAAO,EAAE;QACtD,EAAE,IAAI,EAAE,gBAAgB,EAAE,OAAO,EAAE,MAAM,EAAE;QAC3C,EAAE,IAAI,EAAE,iBAAiB,EAAE,OAAO,EAAE,GAAG,EAAE;QACzC,EAAE,IAAI,EAAE,uBAAuB,EAAE,OAAO,EAAE,2EAA2E,EAAE;QACvH,EAAE,IAAI,EAAE,cAAc,EAAE,OAAO,EAAE,MAAM,EAAE;QACzC,EAAE,IAAI,EAAE,cAAc,EAAE,OAAO,EAAE,SAAS,EAAE;KAC7C,CAAC;AACJ,CAAC"}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
export const BUNDLED_SKILLS_PACK = {
|
|
2
2
|
"schema": 1,
|
|
3
3
|
"name": "somewhere-skills",
|
|
4
|
-
"version": "1+
|
|
5
|
-
"sha256": "
|
|
4
|
+
"version": "1+a9b0d6a4b518",
|
|
5
|
+
"sha256": "a9b0d6a4b5185d8088357c156a7b5b222ebbbd31639113120818998488bcef50",
|
|
6
6
|
"files": [
|
|
7
7
|
{
|
|
8
8
|
"path": "deploy-verify-loop/SKILL.md",
|
|
@@ -11,13 +11,13 @@ export const BUNDLED_SKILLS_PACK = {
|
|
|
11
11
|
},
|
|
12
12
|
{
|
|
13
13
|
"path": "schema-changes/SKILL.md",
|
|
14
|
-
"sha256": "
|
|
15
|
-
"content": "---\nname: schema-changes\ndescription: Before adding, changing, or removing a table or column in db/schema.ts.\n---\n\n# Change the database schema safely\n\n## The file is the contract\n\nThe default `somewhere init` starter has no `db/schema.ts`: create it at the project root, or start with `somewhere init --features private-data`, which includes one.\n\n```ts\n// db/schema.ts\nimport { id, owner, schema, table, text, timestamp } from 'somewhere/db';\n\nexport default schema({\n notes: table(\n {\n id: id(),\n title: text(),\n body: text({ default: '' }),\n created_at: timestamp({ default: 'now' }),\n },\n {\n scope: owner(),\n client: {\n read: ['id', 'title', 'body', 'created_at'],\n create: ['title', 'body'],\n update: ['title', 'body'],\n delete: true,\n },\n },\n ),\n});\n```\n\nA table without a `client` block can't be reached from the browser at all.\n\
|
|
14
|
+
"sha256": "1b215b59474cec396c53c1fdbc3432b5b3a21f3fa8909580f1d18c640e0f746f",
|
|
15
|
+
"content": "---\nname: schema-changes\ndescription: Before adding, changing, or removing a table or column in db/schema.ts.\n---\n\n# Change the database schema safely\n\n## The file is the contract\n\nThe default `somewhere init` starter has no `db/schema.ts`: create it at the project root, or start with `somewhere init --features private-data`, which includes one.\n\n```ts\n// db/schema.ts\nimport { id, owner, schema, table, text, timestamp } from 'somewhere/db';\n\nexport default schema({\n notes: table(\n {\n id: id(),\n title: text(),\n body: text({ default: '' }),\n created_at: timestamp({ default: 'now' }),\n },\n {\n scope: owner(),\n client: {\n read: ['id', 'title', 'body', 'created_at'],\n create: ['title', 'body'],\n update: ['title', 'body'],\n delete: true,\n },\n },\n ),\n});\n```\n\nA table without a `client` block can't be reached from the browser at all.\n\nBefore the first deploy, delete an unused starter table declaration outright: there is no deployed table to retire. After a table has been deployed, use `removedTable()` as described above, including when the table is empty.\n\nDeclare a file collection in `db/schema.ts`: who may upload, read, replace and delete its files.\n\nRun `somewhere typecheck` before deploying schema changes.\n\n## What a deploy does with it\n\n- **Additive changes apply**: a new table, a new nullable-or-defaulted column, a new index, a new unique group. Unchanged schema is a no-op.\n- **Unmarked removals and shape changes refuse** with `409 SCHEMA_DEPLOY_REFUSED` and a message naming the change.\n- **Removing a table** is `old_table: removedTable()`.\n- once the new version is live it retires the table and keeps its data for 30 days.\n- a production deploy or a promotion that would remove or rename a column is refused before anything changes, so a running release never loses a column it uses. Keep the column declared and leave its data in place.\n\n## Failure: raw SQL refused after the schema file deploys\n\nOn an older shared database, ordinary `sw.db.query` / `sw.db.batch` fail before transport with `MANAGED_RAW_SQL_REQUIRES_SERVER_AUTHORITY`, including in job, queue, and cron handlers; with a separate SQL database they run there and never see declared tables. Fix: write with `sw.db.insert` / `sw.db.update` / `sw.db.remove` (the table needs a declared intent)\n\nSources (`somewhere docs <topic>`): declared-data, declared-files, getting-started, sw.db, troubleshooting.\n"
|
|
16
16
|
},
|
|
17
17
|
{
|
|
18
18
|
"path": "sign-in-setup/SKILL.md",
|
|
19
|
-
"sha256": "
|
|
20
|
-
"content": "---\nname: sign-in-setup\ndescription: When the app needs users to sign up, sign in, or sign out.\n---\n\n# Set up sign-in\n\n## Server: one route file\n\n`login` / `signup` are developer-key-gated (the browser can't call them), so one server route mediates them and sets the session cookies.\n\n```ts\n// api/auth/[...path].ts\nexport { somewhereAuth as default } from '@somewhere-cloud/sdk/server';\n```\n\nIt serves `POST /signup`, `/login`, `/logout`, `/magic-link`, `/magic-link/verify`, `GET /me`, and the Google/GitHub/Discord `GET /<provider>-url` + `POST /<provider>` code exchange.\n\n## Page: the SDK client\n\n```bash\nnpm i @somewhere-cloud/sdk\n```\n\n```ts\n// src/auth.ts — page code\nimport { createSomewhereAuth } from '@somewhere-cloud/sdk/auth'\n\nexport const auth = createSomewhereAuth()\n\n// Call from your sign-up form; throws AuthError with the message on failure.\nexport async function signUp(email: string, password: string) {\n await auth.signUp({ email, password }) // or auth.signIn({ email, password })\n return auth.getUser() // the signed-in user, or null\n}\nexport async function signOut() {\n await auth.signOut();\n if (auth.getState().signOutUnconfirmed) {\n throw new Error('Sign-out could not be confirmed. Please try again.');\n }\n // Only navigate or reload after confirmed logout.\n}\n```\n\nAwait `signOut()` in the click handler before navigating or reloading. While it is pending, keep the current screen or show a disabled signing-out state. Do not use the appearance of a signed-out form as proof that the server session has ended. After awaiting, check `auth.getState().signOutUnconfirmed`; show a retry message when true. `signOut()` can settle without confirming server logout.\n\nCalls to your own `api/*` functions just send `credentials: 'include'`.\n\nDon't write `getCookie()` / token-parsing helpers → `sw.auth.fromRequest(req)` reads cookie + Bearer header and returns the validated user (or null) in one call.\n\nMail to `<name>@<project>.test.somewhere.site` is read with `somewhere email test-inbox <address>`.\n\n## Failure 1: sign-in errors\n\nexpected failures (wrong password, duplicate email, weak password) come back as structured 4xx with the real message, never an opaque 500.\n\n## Failure 2: AUTH_REQUIRED from an owner() table\n\nThe table is user-owned, so the platform scopes it to a principal, and this request had none: there is no signed-in user, and this table does not declare `owner({ visitors: true })`, which is the declaration that accepts a stable anonymous visitor identity.\n\nSources (`somewhere docs <topic>`): auth-client, common-mistakes, recipe-signed-in-app, sdk, troubleshooting.\n"
|
|
19
|
+
"sha256": "6b729ec43cf5572321ba4cd7ff4eccb28c35ebacb925d22ef1b8fb0eca4c5093",
|
|
20
|
+
"content": "---\nname: sign-in-setup\ndescription: When the app needs users to sign up, sign in, or sign out.\n---\n\n# Set up sign-in\n\n## Server: one route file\n\n`login` / `signup` are developer-key-gated (the browser can't call them), so one server route mediates them and sets the session cookies.\n\n```ts\n// api/auth/[...path].ts\nexport { somewhereAuth as default } from '@somewhere-cloud/sdk/server';\n```\n\nIt serves `POST /signup`, `/login`, `/logout`, `/magic-link`, `/magic-link/verify`, `GET /me`, and the Google/GitHub/Discord `GET /<provider>-url` + `POST /<provider>` code exchange.\n\n## Client and React state reference\n\nRead `docs({ topic: 'auth-client', section: 'react-auth-state' })` for the SDK's React state contract. Extend the starter's existing provider and auth client.\n\n## Page: the SDK client\n\n```bash\nnpm i @somewhere-cloud/sdk\n```\n\n```ts\n// src/auth.ts — page code\nimport { createSomewhereAuth } from '@somewhere-cloud/sdk/auth'\n\nexport const auth = createSomewhereAuth()\n\n// Call from your sign-up form; throws AuthError with the message on failure.\nexport async function signUp(email: string, password: string) {\n await auth.signUp({ email, password }) // or auth.signIn({ email, password })\n return auth.getUser() // the signed-in user, or null\n}\nexport async function signOut() {\n await auth.signOut();\n if (auth.getState().signOutUnconfirmed) {\n throw new Error('Sign-out could not be confirmed. Please try again.');\n }\n // Only navigate or reload after confirmed logout.\n}\n```\n\nAwait `signOut()` in the click handler before navigating or reloading. While it is pending, keep the current screen or show a disabled signing-out state. Do not use the appearance of a signed-out form as proof that the server session has ended. After awaiting, check `auth.getState().signOutUnconfirmed`; show a retry message when true. `signOut()` can settle without confirming server logout.\n\nCalls to your own `api/*` functions just send `credentials: 'include'`.\n\nDon't write `getCookie()` / token-parsing helpers → `sw.auth.fromRequest(req)` reads cookie + Bearer header and returns the validated user (or null) in one call.\n\nMail to `<name>@<project>.test.somewhere.site` is read with `somewhere email test-inbox <address>`.\n\n## Failure 1: sign-in errors\n\nexpected failures (wrong password, duplicate email, weak password) come back as structured 4xx with the real message, never an opaque 500.\n\n## Failure 2: AUTH_REQUIRED from an owner() table\n\nThe table is user-owned, so the platform scopes it to a principal, and this request had none: there is no signed-in user, and this table does not declare `owner({ visitors: true })`, which is the declaration that accepts a stable anonymous visitor identity.\n\nSources (`somewhere docs <topic>`): auth-client, common-mistakes, recipe-signed-in-app, sdk, troubleshooting.\n"
|
|
21
21
|
},
|
|
22
22
|
{
|
|
23
23
|
"path": "troubleshooting/SKILL.md",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"skills-pack.generated.js","sourceRoot":"","sources":["../../src/lib/skills-pack.generated.ts"],"names":[],"mappings":"AAIA,MAAM,CAAC,MAAM,mBAAmB,GAAe;IAC7C,QAAQ,EAAE,CAAC;IACX,MAAM,EAAE,kBAAkB;IAC1B,SAAS,EAAE,gBAAgB;IAC3B,QAAQ,EAAE,kEAAkE;IAC5E,OAAO,EAAE;QACP;YACE,MAAM,EAAE,6BAA6B;YACrC,QAAQ,EAAE,kEAAkE;YAC5E,SAAS,EAAE,mnEAAmnE;SAC/nE;QACD;YACE,MAAM,EAAE,yBAAyB;YACjC,QAAQ,EAAE,kEAAkE;YAC5E,SAAS,EAAE,
|
|
1
|
+
{"version":3,"file":"skills-pack.generated.js","sourceRoot":"","sources":["../../src/lib/skills-pack.generated.ts"],"names":[],"mappings":"AAIA,MAAM,CAAC,MAAM,mBAAmB,GAAe;IAC7C,QAAQ,EAAE,CAAC;IACX,MAAM,EAAE,kBAAkB;IAC1B,SAAS,EAAE,gBAAgB;IAC3B,QAAQ,EAAE,kEAAkE;IAC5E,OAAO,EAAE;QACP;YACE,MAAM,EAAE,6BAA6B;YACrC,QAAQ,EAAE,kEAAkE;YAC5E,SAAS,EAAE,mnEAAmnE;SAC/nE;QACD;YACE,MAAM,EAAE,yBAAyB;YACjC,QAAQ,EAAE,kEAAkE;YAC5E,SAAS,EAAE,g+EAAg+E;SAC5+E;QACD;YACE,MAAM,EAAE,wBAAwB;YAChC,QAAQ,EAAE,kEAAkE;YAC5E,SAAS,EAAE,k2FAAk2F;SAC92F;QACD;YACE,MAAM,EAAE,0BAA0B;YAClC,QAAQ,EAAE,kEAAkE;YAC5E,SAAS,EAAE,s2DAAs2D;SACl3D;QACD;YACE,MAAM,EAAE,kCAAkC;YAC1C,QAAQ,EAAE,kEAAkE;YAC5E,SAAS,EAAE,uvEAAuvE;SACnwE;QACD;YACE,MAAM,EAAE,+BAA+B;YACvC,QAAQ,EAAE,kEAAkE;YAC5E,SAAS,EAAE,k3DAAk3D;SAC93D;QACD;YACE,MAAM,EAAE,iBAAiB;YACzB,QAAQ,EAAE,kEAAkE;YAC5E,SAAS,EAAE,65FAA65F;SACz6F;KACF;CACF,CAAC"}
|
package/npm-shrinkwrap.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@somewhere-cloud/cli",
|
|
3
|
-
"version": "0.38.
|
|
3
|
+
"version": "0.38.1",
|
|
4
4
|
"lockfileVersion": 3,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"packages": {
|
|
7
7
|
"": {
|
|
8
8
|
"name": "@somewhere-cloud/cli",
|
|
9
|
-
"version": "0.38.
|
|
9
|
+
"version": "0.38.1",
|
|
10
10
|
"bundleDependencies": [
|
|
11
11
|
"@modelcontextprotocol/sdk",
|
|
12
12
|
"chokidar",
|