@inneranimalmedia/agentsam-sdk 1.9.0 → 2.0.0-alpha.identity.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/DEVELOPMENT.md +21 -4
- package/README.md +11 -3
- package/docs/RELEASES.iam-mirror.md +2 -2
- package/docs/RELEASES.md +6 -2
- package/docs/identity/README.md +11 -0
- package/examples/gorilla-shell/README.md +7 -14
- package/package.json +14 -5
- package/packages/identity/README.md +68 -0
- package/packages/identity/backend/README.md +26 -0
- package/packages/identity/docs/getting-started.md +16 -0
- package/packages/identity/examples/cloudflare-worker/README.md +5 -0
- package/packages/identity/examples/legendary-os/README.md +27 -0
- package/packages/identity/package.json +30 -0
- package/packages/identity/scripts/postinstall-hint.mjs +8 -0
- package/packages/identity/scripts/preview-auth-portal.mjs +260 -0
- package/packages/identity/src/adapters/cloudflare-d1/index.js +4 -0
- package/packages/identity/src/adapters/inneranimalmedia/README.md +7 -0
- package/packages/identity/src/contracts/external-identity.js +35 -0
- package/packages/identity/src/contracts/identity.js +17 -0
- package/packages/identity/src/contracts/provider.js +8 -0
- package/packages/identity/src/contracts/session.js +9 -0
- package/packages/identity/src/core/accounts.js +4 -0
- package/packages/identity/src/core/browser-paths.js +34 -0
- package/packages/identity/src/core/constants.js +9 -0
- package/packages/identity/src/core/errors.js +8 -0
- package/packages/identity/src/core/http-json.js +10 -0
- package/packages/identity/src/core/identity.js +4 -0
- package/packages/identity/src/core/index.js +10 -0
- package/packages/identity/src/core/password-crypto.js +53 -0
- package/packages/identity/src/core/recovery.js +4 -0
- package/packages/identity/src/core/sessions.js +59 -0
- package/packages/identity/src/frontend/auth-portal/README.md +52 -0
- package/packages/identity/src/frontend/auth-portal/pages/login.html +821 -0
- package/packages/identity/src/frontend/auth-portal/pages/reset.html +582 -0
- package/packages/identity/src/frontend/auth-portal/pages/signup.html +835 -0
- package/packages/identity/src/frontend/auth-portal/preview/dashboard-stub.html +22 -0
- package/packages/identity/src/index.js +118 -0
- package/packages/identity/src/migrations/README.md +5 -0
- package/packages/identity/src/oauth/README.md +4 -0
- package/packages/identity/src/oauth/callback.js +24 -0
- package/packages/identity/src/provider-contract.js +61 -0
- package/packages/identity/src/providers/email/index.js +39 -0
- package/packages/identity/src/providers/gcp/index.js +58 -0
- package/packages/identity/src/providers/github/index.js +14 -0
- package/packages/identity/src/providers/github/mapper.js +22 -0
- package/packages/identity/src/providers/github/oauth.js +43 -0
- package/packages/identity/src/providers/github/profile.js +34 -0
- package/packages/identity/src/providers/google/index.js +14 -0
- package/packages/identity/src/providers/google/mapper.js +32 -0
- package/packages/identity/src/providers/google/oauth.js +41 -0
- package/packages/identity/src/providers/google/profile.js +14 -0
- package/packages/identity/src/providers/index.js +25 -0
- package/packages/identity/tests/identity.test.mjs +74 -0
- package/packages/identity/tests/preview-auth-portal.test.mjs +38 -0
- package/python/README.md +8 -1
- package/python/agentsam_sdk/repository/__init__.py +4 -18
- package/python/docs/gaps.md +9 -0
- package/python/docs/tooling.md +5 -1
- package/python/tests/test_d1_bloat.py +1 -1
- package/src/cli.js +15 -0
- package/src/commands/identity-preview.js +45 -0
- package/src/index.js +16 -0
- package/src/lib/core-client.js +5 -0
- package/templates/gorilla-shell/App.tsx +28 -28
- package/templates/gorilla-shell/README.md +15 -3
- package/test/smoke.mjs +5 -0
- package/examples/gorilla-shell/App.tsx +0 -540
- package/examples/gorilla-shell/index.html +0 -15
- package/examples/gorilla-shell/main.jsx +0 -9
- package/examples/gorilla-shell/package.json +0 -19
- package/examples/gorilla-shell/vite.config.js +0 -10
- package/src/commands/http-server.js +0 -97
package/DEVELOPMENT.md
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Developing agentsam-sdk with Inner Animal Media
|
|
2
2
|
|
|
3
3
|
## Local smoke test
|
|
4
4
|
|
|
5
5
|
```bash
|
|
6
6
|
cd agentsam-sdk
|
|
7
7
|
npm test
|
|
8
|
+
npm run preview:auth-portal # opens /auth/login at http://127.0.0.1:8791
|
|
8
9
|
```
|
|
9
10
|
|
|
10
11
|
## Link into a scaffolded project
|
|
@@ -47,9 +48,25 @@ npx agentsam init \
|
|
|
47
48
|
2. `npm test` passes
|
|
48
49
|
3. Bump version in root `package.json`
|
|
49
50
|
4. Confirm `files` includes consumer surfaces (`src`, `bin`, `python`, `protocol`, …)
|
|
50
|
-
5. `npm
|
|
51
|
-
6.
|
|
52
|
-
7.
|
|
51
|
+
5. `bash scripts/npm-publish-preflight.sh` — must print `npm whoami: inneranimalmedia`
|
|
52
|
+
6. `npm publish --tag alpha --access public` (or `--tag latest` for stable)
|
|
53
|
+
7. Tag: `git tag vX.Y.Z && git push origin vX.Y.Z`
|
|
54
|
+
8. Record pairing in [`docs/RELEASES.md`](./docs/RELEASES.md): `iam@<40-sha> ↔ @inneranimalmedia/agentsam-sdk@X.Y.Z`
|
|
55
|
+
|
|
56
|
+
### Publish 404 (`PUT … Not found`)
|
|
57
|
+
|
|
58
|
+
npm returns **404** (not 403) when you are logged in as the **wrong user** for scope `@inneranimalmedia`.
|
|
59
|
+
|
|
60
|
+
- Registry maintainer for this package: **`inneranimalmedia`** (see `npm view @inneranimalmedia/agentsam-sdk maintainers`)
|
|
61
|
+
- Fix: `npm whoami` must be `inneranimalmedia`
|
|
62
|
+
```bash
|
|
63
|
+
npm logout
|
|
64
|
+
npm login # npm user inneranimalmedia (org owner), not personal GitHub-linked account
|
|
65
|
+
bash scripts/npm-publish-preflight.sh
|
|
66
|
+
npm publish --tag alpha --access public
|
|
67
|
+
```
|
|
68
|
+
- If you use a team org on npmjs.com, invite your daily npm user as **Developer** on the org with publish rights.
|
|
69
|
+
- Always pass `--access public` (already in `package.json` `publishConfig`; flag is harmless).
|
|
53
70
|
|
|
54
71
|
Workspace packages under `packages/*` (e.g. `@inneranimalmedia/agentsam-shell-kit`) stay
|
|
55
72
|
`private: true` until separately ready — they are **not** the root publish identity.
|
package/README.md
CHANGED
|
@@ -6,7 +6,7 @@ Agent Sam is a full-stack autonomous agent SDK built on Cloudflare Workers, D1,
|
|
|
6
6
|
|
|
7
7
|
**Repo:** [github.com/SamPrimeaux/agentsam-sdk](https://github.com/SamPrimeaux/agentsam-sdk) · **npm:** `@inneranimalmedia/agentsam-sdk`
|
|
8
8
|
|
|
9
|
-
**Protocol (dual-home, no drift):** [`protocol/README.md`](./protocol/README.md) — every tool/feature lands in this repo **and** `inneranimalmedia/agentsam-sdk/`; npm publish is manual after mirror. Python lane: [`python/`](./python/).
|
|
9
|
+
**Protocol (dual-home, no drift):** [`protocol/README.md`](./protocol/README.md) — every tool/feature lands in this repo **and** `inneranimalmedia/agentsam-sdk/`; npm publish is manual after mirror. Python lane: [`python/`](./python/) (stdlib-only). Optional network Python package: [`packages/agentsam-site-scrape/`](./packages/agentsam-site-scrape/) (live experimental; does not break the stdlib core).
|
|
10
10
|
|
|
11
11
|
---
|
|
12
12
|
|
|
@@ -78,17 +78,25 @@ npx @inneranimalmedia/agentsam-sdk shell
|
|
|
78
78
|
| Piece | Location |
|
|
79
79
|
|-------|----------|
|
|
80
80
|
| Slash command registry | `src/lib/slash-commands.js` |
|
|
81
|
-
| Phase 0 visual prototype | `examples/gorilla-shell/` |
|
|
81
|
+
| Phase 0 visual prototype | `templates/gorilla-shell/` (canonical; `examples/gorilla-shell/` is a pointer) |
|
|
82
82
|
| Architecture + phases | [docs/CLI_SHELL.md](./docs/CLI_SHELL.md) |
|
|
83
83
|
|
|
84
84
|
Run the prototype:
|
|
85
85
|
|
|
86
86
|
```bash
|
|
87
|
-
cd
|
|
87
|
+
cd templates/gorilla-shell && npm install && npm run dev
|
|
88
88
|
```
|
|
89
89
|
|
|
90
90
|
---
|
|
91
91
|
|
|
92
|
+
## Architecture (CORE default)
|
|
93
|
+
|
|
94
|
+
`src/lib/core-client.js` defaults to `https://inneranimalmedia.com`. **Correct as designed** for serving many client projects: the npm package is a thin delivery/CLI client; intelligence, tool catalog, and policy live server-side on IAM CORE.
|
|
95
|
+
|
|
96
|
+
Without an IAM backend (or `IAM_CORE_URL` / `AGENTSAM_CORE_URL` override), strangers who `npm install` get **scaffold + local CLI only** — not a freestanding hosted Agent Sam.
|
|
97
|
+
|
|
98
|
+
---
|
|
99
|
+
|
|
92
100
|
## Installation
|
|
93
101
|
|
|
94
102
|
```bash
|
|
@@ -8,10 +8,10 @@ Canonical npm-side table also lives in the SDK repo: `docs/RELEASES.md`.
|
|
|
8
8
|
| npm version | Published (UTC) | IAM git SHA (40) | Notes |
|
|
9
9
|
|-------------|-----------------|------------------|-------|
|
|
10
10
|
| 1.7.0 | 2026-07-14 | _(pre-receipt)_ | Prior publish |
|
|
11
|
-
| 1.9.0 |
|
|
11
|
+
| 1.9.0 | 2026-08-05T07:12:21.726Z | `fc1628505cb3c9946c149e4c468c2e264d6f381e` | `repository.inspect` + `--dupes`; mirrored from IAM agentsam-sdk |
|
|
12
12
|
| 1.8.0 | 2026-08-02T13:57:12.080Z | `580547301e370b77ec26bd72558979d335feedd9` | `python/` + `protocol/` in tarball; `repository.scan_bloat`; shell-kit under `packages/` |
|
|
13
13
|
|
|
14
|
-
**Latest pairing
|
|
14
|
+
**Latest pairing :** `iam@fc1628505cb3c9946c149e4c468c2e264d6f381e` ↔ `@inneranimalmedia/agentsam-sdk@1.9.0`
|
|
15
15
|
|
|
16
16
|
### Receipt rules
|
|
17
17
|
|
package/docs/RELEASES.md
CHANGED
|
@@ -2,8 +2,12 @@
|
|
|
2
2
|
|
|
3
3
|
| npm version | Published (UTC) | IAM git SHA (40) | Notes |
|
|
4
4
|
|-------------|-----------------|------------------|-------|
|
|
5
|
+
| 2.0.0-alpha.identity | 2026-08-22 | `559bc37267f76790136004f5fa94a2bb3cd6a721` | Identity subpath (`./identity`); auth portal HTML from IAM peel; SDK git `c3a59d3`. |
|
|
6
|
+
| 2.0.0-alpha.identity.1 | _(pending)_ | `559bc37267f76790136004f5fa94a2bb3cd6a721` | `agentsam identity preview` + `preview:auth-portal` local 1:1 auth shell preview. |
|
|
5
7
|
| 1.7.0 | 2026-07-14 | _(pre-receipt)_ | Prior publish |
|
|
6
|
-
| 1.9.0 |
|
|
8
|
+
| 1.9.0 | 2026-08-05T07:12:21.726Z | `fc1628505cb3c9946c149e4c468c2e264d6f381e` | `python/agentsam_sdk/repository/inspect.py` (`--dupes`); CLI `agentsam repository inspect` |
|
|
7
9
|
| 1.8.0 | 2026-08-02T13:57:12.080Z | `580547301e370b77ec26bd72558979d335feedd9` | `python/` + `protocol/` in npm `files`; `repository.scan_bloat`; shell-kit folded to `packages/agentsam-shell-kit` (private). SDK git at publish: `ac52669b89ddb16fad87c42fe53f2c93ef13bd1a`. |
|
|
8
10
|
|
|
9
|
-
**Pairing (
|
|
11
|
+
**Pairing (identity alpha):** `iam@559bc37267f76790136004f5fa94a2bb3cd6a721` ↔ `@inneranimalmedia/agentsam-sdk@2.0.0-alpha.identity`
|
|
12
|
+
|
|
13
|
+
**Pairing (1.9):** `iam@fc1628505cb3c9946c149e4c468c2e264d6f381e` ↔ `@inneranimalmedia/agentsam-sdk@1.9.0`
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
# AgentSam SDK — Identity module
|
|
2
|
+
|
|
3
|
+
See [`packages/identity/README.md`](../packages/identity/README.md).
|
|
4
|
+
|
|
5
|
+
Customer import:
|
|
6
|
+
|
|
7
|
+
```js
|
|
8
|
+
import { createIdentityClient } from '@inneranimalmedia/agentsam-sdk';
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
Alpha: `@inneranimalmedia/agentsam-sdk@2.0.0-alpha.identity`
|
|
@@ -1,22 +1,15 @@
|
|
|
1
|
-
# Gorilla Shell (
|
|
1
|
+
# Gorilla Shell example (superseded)
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
**Canonical scaffold:** [`../../templates/gorilla-shell/`](../../templates/gorilla-shell/)
|
|
4
4
|
|
|
5
|
-
This
|
|
6
|
-
|
|
7
|
-
## Run locally
|
|
5
|
+
This directory previously mirrored an older demo that hard-coded IAM D1/host
|
|
6
|
+
literals. Run and customize from `templates/gorilla-shell` instead:
|
|
8
7
|
|
|
9
8
|
```bash
|
|
10
|
-
cd
|
|
9
|
+
cd templates/gorilla-shell
|
|
11
10
|
npm install
|
|
12
11
|
npm run dev
|
|
13
12
|
```
|
|
14
13
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
- Gorilla launch screen + sprite reactions
|
|
18
|
-
- Themes: NIGHT, DAY, LAVA, VOID
|
|
19
|
-
- Six demo scenarios (deploy, benchmark, D1, tail, samiam, wrangler)
|
|
20
|
-
- Slash command registry lives in `../../src/lib/slash-commands.js`
|
|
21
|
-
|
|
22
|
-
Full architecture: [docs/CLI_SHELL.md](../../docs/CLI_SHELL.md)
|
|
14
|
+
Demo CLI strings there use `{{PROJECT_NAME}}`, `{{D1_DATABASE_ID}}`,
|
|
15
|
+
`{{DASHBOARD_HOST}}`, and related placeholders — not live platform IDs.
|
package/package.json
CHANGED
|
@@ -1,19 +1,24 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@inneranimalmedia/agentsam-sdk",
|
|
3
|
-
"version": "
|
|
4
|
-
"description": "Agent Sam is a full-stack AI agent SDK for autonomous task execution
|
|
3
|
+
"version": "2.0.0-alpha.identity.1",
|
|
4
|
+
"description": "Agent Sam is a full-stack AI agent SDK for autonomous task execution — covering data management, creative workflows, design commands, and multi-step agentic pipelines.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./src/index.js",
|
|
7
7
|
"exports": {
|
|
8
8
|
".": "./src/index.js",
|
|
9
|
+
"./identity": "./packages/identity/src/index.js",
|
|
10
|
+
"./identity/oauth/callback": "./packages/identity/src/oauth/callback.js",
|
|
11
|
+
"./identity/auth-portal/preview": "./packages/identity/scripts/preview-auth-portal.mjs",
|
|
9
12
|
"./package.json": "./package.json"
|
|
10
13
|
},
|
|
11
14
|
"bin": {
|
|
12
15
|
"agentsam": "src/cli.js",
|
|
13
|
-
"agentsam-scaffold": "bin/scaffold.mjs"
|
|
16
|
+
"agentsam-scaffold": "bin/scaffold.mjs",
|
|
17
|
+
"agentsam-auth-portal": "packages/identity/scripts/preview-auth-portal.mjs"
|
|
14
18
|
},
|
|
15
19
|
"files": [
|
|
16
20
|
"src",
|
|
21
|
+
"packages/identity",
|
|
17
22
|
"templates",
|
|
18
23
|
"docs",
|
|
19
24
|
"examples",
|
|
@@ -26,11 +31,15 @@
|
|
|
26
31
|
"DEVELOPMENT.md"
|
|
27
32
|
],
|
|
28
33
|
"workspaces": [
|
|
29
|
-
"packages
|
|
34
|
+
"packages/agentsam-shell-kit",
|
|
35
|
+
"packages/identity"
|
|
30
36
|
],
|
|
31
37
|
"scripts": {
|
|
32
|
-
"test": "node test/smoke.mjs",
|
|
38
|
+
"test": "node test/smoke.mjs && npm --prefix packages/identity test",
|
|
39
|
+
"test:identity": "npm --prefix packages/identity test",
|
|
33
40
|
"smoke": "node test/smoke.mjs",
|
|
41
|
+
"preview:auth-portal": "node packages/identity/scripts/preview-auth-portal.mjs --open",
|
|
42
|
+
"postinstall": "node packages/identity/scripts/postinstall-hint.mjs",
|
|
34
43
|
"prepublishOnly": "npm test"
|
|
35
44
|
},
|
|
36
45
|
"engines": {
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
# Identity (`packages/identity`)
|
|
2
|
+
|
|
3
|
+
**Package #1** inside `@inneranimalmedia/agentsam-sdk` — not a separate npm product.
|
|
4
|
+
|
|
5
|
+
```
|
|
6
|
+
inneranimalmedia (reference) → agentsam-sdk (product) → Legendary-OS (first external proof)
|
|
7
|
+
```
|
|
8
|
+
|
|
9
|
+
## Customer API
|
|
10
|
+
|
|
11
|
+
```js
|
|
12
|
+
import { createIdentityClient } from '@inneranimalmedia/agentsam-sdk';
|
|
13
|
+
|
|
14
|
+
const identity = createIdentityClient({
|
|
15
|
+
portal: { brand: { name: 'Legendary OS', logoUrl: '/logo.svg' } },
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
identity.providers.google();
|
|
19
|
+
identity.login(request); // → Identity Service (server-side)
|
|
20
|
+
identity.session.fromRequest(request);
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
## Layout
|
|
24
|
+
|
|
25
|
+
```
|
|
26
|
+
src/
|
|
27
|
+
core/ identity · sessions · accounts · recovery
|
|
28
|
+
providers/ google · github · gcp · email
|
|
29
|
+
oauth/ authorize/callback (extract from IAM — next sprint)
|
|
30
|
+
adapters/ inneranimalmedia · cloudflare-d1
|
|
31
|
+
contracts/
|
|
32
|
+
frontend/auth-portal/pages/ login · signup · reset (verbatim IAM HTML)
|
|
33
|
+
migrations/
|
|
34
|
+
examples/legendary-os/
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
## SDK philosophy
|
|
38
|
+
|
|
39
|
+
Ship: contracts, clients, adapters, scaffolding.
|
|
40
|
+
|
|
41
|
+
Do **not** ship in the client bundle: password DB logic, OAuth secrets, D1 assumptions.
|
|
42
|
+
|
|
43
|
+
## Publish (alpha)
|
|
44
|
+
|
|
45
|
+
From `main` after tests pass:
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
npm test
|
|
49
|
+
npm publish --tag alpha
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
Install in a customer app:
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
npm install @inneranimalmedia/agentsam-sdk@alpha
|
|
56
|
+
# or pin: @inneranimalmedia/agentsam-sdk@2.0.0-alpha.identity
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
Subpath imports:
|
|
60
|
+
|
|
61
|
+
```js
|
|
62
|
+
import { createIdentityClient } from '@inneranimalmedia/agentsam-sdk';
|
|
63
|
+
import { finalizeInboundOAuth } from '@inneranimalmedia/agentsam-sdk/identity/oauth/callback';
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
## IAM design lab
|
|
67
|
+
|
|
68
|
+
`inneranimalmedia/packages/agentsam-identity/` — contracts experiments only; **not** the package owner.
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# Backend — identity runtime
|
|
2
|
+
|
|
3
|
+
Worker-side identity: providers, OAuth finalize, sessions, adapters.
|
|
4
|
+
|
|
5
|
+
## IAM extraction map (stable production — do not rewrite)
|
|
6
|
+
|
|
7
|
+
| SDK target | IAM source today | Notes |
|
|
8
|
+
|------------|------------------|-------|
|
|
9
|
+
| `providers/google/*` | `src/core/auth/providers/google.js` | ✅ ported Sprint 2 |
|
|
10
|
+
| `providers/github/*` | `src/core/auth/providers/github.js` | ✅ ported Sprint 2 |
|
|
11
|
+
| `oauth/callback.js` | `src/api/oauth-login-callbacks.js` → `finalizeInboundOAuth` | **bulletproof path** |
|
|
12
|
+
| `oauth/authorize.js` | `src/api/auth.js` OAuth start handlers | PKCE + state |
|
|
13
|
+
| `core/session-service.js` | `src/core/auth.js` | cookie, `createLoginSession`, revoke |
|
|
14
|
+
| `core/account-linking.js` | `ensureIdentityPlaneBeforeSession`, `ensureAppUser` | account_identities |
|
|
15
|
+
| `adapters/inneranimalmedia/*` | D1 writes in auth side-effects | tenant/workspace stays adapter-only |
|
|
16
|
+
|
|
17
|
+
## Rule
|
|
18
|
+
|
|
19
|
+
Move files; **do not** change OAuth behavior until IAM runs parallel proof (existing users, Google/GitHub callbacks, session cookie).
|
|
20
|
+
|
|
21
|
+
## Public entry
|
|
22
|
+
|
|
23
|
+
```js
|
|
24
|
+
import { createIdentity, GoogleProvider } from '@agentsam/identity';
|
|
25
|
+
// resolves to backend/index.js
|
|
26
|
+
```
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# Getting started with @agentsam/identity
|
|
2
|
+
|
|
3
|
+
1. Install: `npm install @agentsam/identity`
|
|
4
|
+
2. Configure providers and storage adapter
|
|
5
|
+
3. Wire Worker routes for OAuth callback + session cookie
|
|
6
|
+
|
|
7
|
+
Full plan: Phase 1–9 in IAM `plans/active/AGENTSAM-IDENTITY-SDK-PRODUCTIZATION-2026-08.md`
|
|
8
|
+
|
|
9
|
+
```js
|
|
10
|
+
import { createIdentity, GoogleProvider } from '@agentsam/identity';
|
|
11
|
+
|
|
12
|
+
const identity = createIdentity({
|
|
13
|
+
providers: [GoogleProvider],
|
|
14
|
+
storage: { adapter: 'cloudflare-d1', binding: 'DB' },
|
|
15
|
+
});
|
|
16
|
+
```
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# Legendary-OS — @agentsam/identity customer proof
|
|
2
|
+
|
|
3
|
+
Target: fresh install path (Phase 7).
|
|
4
|
+
|
|
5
|
+
## Day 1
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install @agentsam/identity
|
|
9
|
+
npx agentsam identity init --adapter cloudflare-d1
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
## Day 2 proof checklist
|
|
13
|
+
|
|
14
|
+
- [ ] Email signup → session cookie
|
|
15
|
+
- [ ] Email login
|
|
16
|
+
- [ ] Logout clears session
|
|
17
|
+
- [ ] Google OAuth round-trip
|
|
18
|
+
- [ ] GitHub OAuth round-trip
|
|
19
|
+
|
|
20
|
+
## Day 3
|
|
21
|
+
|
|
22
|
+
- [ ] Workspace creation on first login
|
|
23
|
+
- [ ] Dashboard requires auth
|
|
24
|
+
|
|
25
|
+
Record curl transcripts and D1 row counts in `PROOF.md` when complete.
|
|
26
|
+
|
|
27
|
+
See: `inneranimalmedia/plans/active/AGENTSAM-IDENTITY-SDK-PRODUCTIZATION-2026-08.md`
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@inneranimalmedia/agentsam-sdk-identity",
|
|
3
|
+
"version": "2.0.0-alpha.identity.1",
|
|
4
|
+
"private": true,
|
|
5
|
+
"type": "module",
|
|
6
|
+
"description": "Identity module for @inneranimalmedia/agentsam-sdk (workspace — publish via root SDK)",
|
|
7
|
+
"main": "./src/index.js",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": "./src/index.js",
|
|
10
|
+
"./provider-contract": "./src/provider-contract.js",
|
|
11
|
+
"./providers": "./src/providers/index.js",
|
|
12
|
+
"./providers/google": "./src/providers/google/index.js",
|
|
13
|
+
"./providers/github": "./src/providers/github/index.js",
|
|
14
|
+
"./providers/gcp": "./src/providers/gcp/index.js",
|
|
15
|
+
"./providers/email": "./src/providers/email/index.js",
|
|
16
|
+
"./contracts/identity": "./src/contracts/identity.js",
|
|
17
|
+
"./contracts/session": "./src/contracts/session.js",
|
|
18
|
+
"./contracts/provider": "./src/contracts/provider.js",
|
|
19
|
+
"./contracts/external-identity": "./src/contracts/external-identity.js",
|
|
20
|
+
"./oauth/callback": "./src/oauth/callback.js",
|
|
21
|
+
"./frontend/auth-portal/*": "./src/frontend/auth-portal/*"
|
|
22
|
+
},
|
|
23
|
+
"scripts": {
|
|
24
|
+
"test": "node --test tests/*.test.mjs",
|
|
25
|
+
"preview:auth-portal": "node scripts/preview-auth-portal.mjs --open"
|
|
26
|
+
},
|
|
27
|
+
"engines": {
|
|
28
|
+
"node": ">=20"
|
|
29
|
+
}
|
|
30
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
if (process.env.CI || process.env.AGENTSAM_SDK_SKIP_POSTINSTALL) process.exit(0);
|
|
3
|
+
|
|
4
|
+
console.log(`
|
|
5
|
+
@inneranimalmedia/agentsam-sdk — auth portal preview (local, 1:1 IAM HTML):
|
|
6
|
+
npx agentsam identity preview --open
|
|
7
|
+
npm run preview:auth-portal
|
|
8
|
+
`);
|
|
@@ -0,0 +1,260 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Local static preview for IAM auth portal HTML (1:1 paths: /auth/login, /auth/signup, /auth/reset).
|
|
4
|
+
* API routes are stubbed so forms and globe-exit transitions work without a Worker.
|
|
5
|
+
*/
|
|
6
|
+
import http from 'node:http';
|
|
7
|
+
import fs from 'node:fs/promises';
|
|
8
|
+
import path from 'node:path';
|
|
9
|
+
import { fileURLToPath } from 'node:url';
|
|
10
|
+
import { spawn } from 'node:child_process';
|
|
11
|
+
|
|
12
|
+
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
13
|
+
export const AUTH_PORTAL_PAGES_DIR = path.resolve(__dirname, '../src/frontend/auth-portal/pages');
|
|
14
|
+
const PREVIEW_DIR = path.resolve(__dirname, '../src/frontend/auth-portal/preview');
|
|
15
|
+
|
|
16
|
+
const PAGE_ROUTES = {
|
|
17
|
+
'/auth/login': 'login.html',
|
|
18
|
+
'/auth/signup': 'signup.html',
|
|
19
|
+
'/auth/reset': 'reset.html',
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
const MIME = {
|
|
23
|
+
'.html': 'text/html; charset=utf-8',
|
|
24
|
+
'.css': 'text/css; charset=utf-8',
|
|
25
|
+
'.js': 'application/javascript; charset=utf-8',
|
|
26
|
+
'.svg': 'image/svg+xml',
|
|
27
|
+
'.png': 'image/png',
|
|
28
|
+
'.jpg': 'image/jpeg',
|
|
29
|
+
'.webp': 'image/webp',
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
function parseArgs(argv) {
|
|
33
|
+
const opts = { port: 8791, host: '127.0.0.1', open: false };
|
|
34
|
+
for (let i = 0; i < argv.length; i += 1) {
|
|
35
|
+
const arg = argv[i];
|
|
36
|
+
if (arg === '--open' || arg === '-o') opts.open = true;
|
|
37
|
+
else if (arg === '--port' || arg === '-p') opts.port = Number(argv[++i]) || opts.port;
|
|
38
|
+
else if (arg === '--host' || arg === '-H') opts.host = argv[++i] || opts.host;
|
|
39
|
+
else if (arg === '--help' || arg === '-h') {
|
|
40
|
+
console.log(`
|
|
41
|
+
Auth portal preview — same routes as IAM production HTML shells
|
|
42
|
+
|
|
43
|
+
Usage:
|
|
44
|
+
agentsam identity preview [--port 8791] [--open]
|
|
45
|
+
npm run preview:auth-portal
|
|
46
|
+
|
|
47
|
+
Pages:
|
|
48
|
+
/auth/login /auth/signup /auth/reset
|
|
49
|
+
|
|
50
|
+
Preview credentials (any host): email preview@example.com · password preview
|
|
51
|
+
OAuth buttons → stub page with link to globe-exit demo
|
|
52
|
+
`);
|
|
53
|
+
process.exit(0);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
return opts;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
function json(res, status, body) {
|
|
60
|
+
const payload = JSON.stringify(body);
|
|
61
|
+
res.writeHead(status, {
|
|
62
|
+
'Content-Type': 'application/json; charset=utf-8',
|
|
63
|
+
'Content-Length': Buffer.byteLength(payload),
|
|
64
|
+
});
|
|
65
|
+
res.end(payload);
|
|
66
|
+
return true;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
async function readText(filePath) {
|
|
70
|
+
return fs.readFile(filePath, 'utf8');
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
async function serveFile(res, filePath) {
|
|
74
|
+
const ext = path.extname(filePath);
|
|
75
|
+
const body = await fs.readFile(filePath);
|
|
76
|
+
res.writeHead(200, { 'Content-Type': MIME[ext] || 'application/octet-stream' });
|
|
77
|
+
res.end(body);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
function hubHtml(baseUrl) {
|
|
81
|
+
return `<!DOCTYPE html>
|
|
82
|
+
<html lang="en">
|
|
83
|
+
<head>
|
|
84
|
+
<meta charset="UTF-8" />
|
|
85
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
86
|
+
<title>Auth portal preview | Agent Sam SDK</title>
|
|
87
|
+
<style>
|
|
88
|
+
body { font-family: Inter, system-ui, sans-serif; background: #050508; color: #e2e8f0; margin: 0; padding: 32px; line-height: 1.5; }
|
|
89
|
+
main { max-width: 640px; margin: 0 auto; }
|
|
90
|
+
h1 { font-size: 1.35rem; margin-bottom: 0.25rem; }
|
|
91
|
+
p.muted { color: #94a3b8; font-size: 0.95rem; }
|
|
92
|
+
ul { padding-left: 1.2rem; }
|
|
93
|
+
a { color: #38bdf8; }
|
|
94
|
+
code { background: rgba(255,255,255,0.08); padding: 2px 6px; border-radius: 4px; }
|
|
95
|
+
.card { margin-top: 24px; padding: 20px; border: 1px solid rgba(255,255,255,0.12); border-radius: 12px; background: rgba(255,255,255,0.04); }
|
|
96
|
+
</style>
|
|
97
|
+
</head>
|
|
98
|
+
<body>
|
|
99
|
+
<main>
|
|
100
|
+
<h1>Auth portal preview</h1>
|
|
101
|
+
<p class="muted">Static HTML copied from IAM <code>static/pages/auth/*</code> — paths match production.</p>
|
|
102
|
+
<div class="card">
|
|
103
|
+
<strong>Pages</strong>
|
|
104
|
+
<ul>
|
|
105
|
+
<li><a href="${baseUrl}/auth/login">/auth/login</a></li>
|
|
106
|
+
<li><a href="${baseUrl}/auth/signup">/auth/signup</a></li>
|
|
107
|
+
<li><a href="${baseUrl}/auth/reset">/auth/reset</a></li>
|
|
108
|
+
<li><a href="${baseUrl}/auth/login?globe_exit=1&next=/preview/dashboard">Globe exit demo</a></li>
|
|
109
|
+
</ul>
|
|
110
|
+
<p><strong>Preview login:</strong> <code>preview@example.com</code> / <code>preview</code> (triggers success + globe transition)</p>
|
|
111
|
+
<p class="muted">OAuth buttons open a stub — use the globe-exit link to verify the post-login animation.</p>
|
|
112
|
+
</div>
|
|
113
|
+
</main>
|
|
114
|
+
</body>
|
|
115
|
+
</html>`;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
function oauthStubHtml(provider, baseUrl) {
|
|
119
|
+
const label = provider === 'github' ? 'GitHub' : 'Google';
|
|
120
|
+
return `<!DOCTYPE html>
|
|
121
|
+
<html lang="en"><head><meta charset="UTF-8" /><title>OAuth preview (${label})</title>
|
|
122
|
+
<style>body{font-family:system-ui;background:#050508;color:#e2e8f0;padding:32px;max-width:520px;margin:auto;line-height:1.5}a{color:#38bdf8}</style>
|
|
123
|
+
</head><body>
|
|
124
|
+
<h1>OAuth preview — ${label}</h1>
|
|
125
|
+
<p>In production this redirects to the provider. In preview mode, use the link below to simulate a successful return and globe exit.</p>
|
|
126
|
+
<p><a href="${baseUrl}/auth/login?globe_exit=1&next=/preview/dashboard">Simulate OAuth success (globe exit)</a></p>
|
|
127
|
+
<p><a href="${baseUrl}/auth/login">Back to sign in</a></p>
|
|
128
|
+
</body></html>`;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
async function handleApi(req, res, url) {
|
|
132
|
+
const { pathname } = url;
|
|
133
|
+
if (req.method === 'POST' && pathname === '/api/auth/login') {
|
|
134
|
+
let body = '';
|
|
135
|
+
for await (const chunk of req) body += chunk;
|
|
136
|
+
let parsed = {};
|
|
137
|
+
try { parsed = JSON.parse(body || '{}'); } catch { /* preview */ }
|
|
138
|
+
const email = String(parsed.email || '').trim().toLowerCase();
|
|
139
|
+
const password = String(parsed.password || '');
|
|
140
|
+
if (email === 'preview@example.com' && password === 'preview') {
|
|
141
|
+
return json(res, 200, {
|
|
142
|
+
ok: true,
|
|
143
|
+
redirect: parsed.next && String(parsed.next).startsWith('/') ? parsed.next : '/preview/dashboard',
|
|
144
|
+
});
|
|
145
|
+
}
|
|
146
|
+
return json(res, 401, { ok: false, error: 'Invalid Identity or Access Key (preview: preview@example.com / preview)' });
|
|
147
|
+
}
|
|
148
|
+
if (req.method === 'POST' && pathname === '/api/auth/backup-code') {
|
|
149
|
+
return json(res, 200, { ok: true, redirect: '/preview/dashboard' });
|
|
150
|
+
}
|
|
151
|
+
if (req.method === 'POST' && pathname === '/api/auth/password-reset/request') {
|
|
152
|
+
return json(res, 200, { ok: true, message: 'If an account exists, a reset link was sent (preview stub).' });
|
|
153
|
+
}
|
|
154
|
+
if (req.method === 'POST' && pathname === '/api/auth/password-reset/confirm') {
|
|
155
|
+
return json(res, 200, { ok: true, redirect: '/auth/login?reset=success' });
|
|
156
|
+
}
|
|
157
|
+
if (req.method === 'GET' && pathname.startsWith('/api/oauth/')) {
|
|
158
|
+
const provider = pathname.includes('github') ? 'github' : 'google';
|
|
159
|
+
const baseUrl = `${url.protocol}//${url.host}`;
|
|
160
|
+
res.writeHead(200, { 'Content-Type': 'text/html; charset=utf-8' });
|
|
161
|
+
res.end(oauthStubHtml(provider, baseUrl));
|
|
162
|
+
return true;
|
|
163
|
+
}
|
|
164
|
+
return false;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
export async function createAuthPortalPreviewServer(opts = {}) {
|
|
168
|
+
const host = opts.host ?? '127.0.0.1';
|
|
169
|
+
const port = opts.port ?? 8791;
|
|
170
|
+
|
|
171
|
+
const server = http.createServer(async (req, res) => {
|
|
172
|
+
try {
|
|
173
|
+
const url = new URL(req.url || '/', `http://${req.headers.host || `${host}:${port}`}`);
|
|
174
|
+
|
|
175
|
+
if (await handleApi(req, res, url)) return;
|
|
176
|
+
|
|
177
|
+
if (req.method !== 'GET' && req.method !== 'HEAD') {
|
|
178
|
+
res.writeHead(405);
|
|
179
|
+
res.end('Method not allowed');
|
|
180
|
+
return;
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
if (url.pathname === '/' || url.pathname === '/preview') {
|
|
184
|
+
const baseUrl = `${url.protocol}//${url.host}`;
|
|
185
|
+
res.writeHead(200, { 'Content-Type': 'text/html; charset=utf-8' });
|
|
186
|
+
res.end(hubHtml(baseUrl));
|
|
187
|
+
return;
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
const pageFile = PAGE_ROUTES[url.pathname];
|
|
191
|
+
if (pageFile) {
|
|
192
|
+
await serveFile(res, path.join(AUTH_PORTAL_PAGES_DIR, pageFile));
|
|
193
|
+
return;
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
if (url.pathname === '/preview/dashboard') {
|
|
197
|
+
const file = path.join(PREVIEW_DIR, 'dashboard-stub.html');
|
|
198
|
+
await serveFile(res, file);
|
|
199
|
+
return;
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
res.writeHead(404, { 'Content-Type': 'text/plain; charset=utf-8' });
|
|
203
|
+
res.end('Not found');
|
|
204
|
+
} catch (err) {
|
|
205
|
+
res.writeHead(500, { 'Content-Type': 'text/plain; charset=utf-8' });
|
|
206
|
+
res.end(err?.message || 'Server error');
|
|
207
|
+
}
|
|
208
|
+
});
|
|
209
|
+
|
|
210
|
+
await new Promise((resolve, reject) => {
|
|
211
|
+
server.once('error', reject);
|
|
212
|
+
server.listen(port, host, resolve);
|
|
213
|
+
});
|
|
214
|
+
|
|
215
|
+
const address = server.address();
|
|
216
|
+
const boundPort = typeof address === 'object' && address ? address.port : port;
|
|
217
|
+
const baseUrl = `http://${host}:${boundPort}`;
|
|
218
|
+
|
|
219
|
+
return { server, host, port: boundPort, baseUrl };
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
function openBrowser(url) {
|
|
223
|
+
const platform = process.platform;
|
|
224
|
+
const cmd = platform === 'darwin' ? 'open' : platform === 'win32' ? 'start' : 'xdg-open';
|
|
225
|
+
const child = spawn(cmd, [url], { stdio: 'ignore', detached: true });
|
|
226
|
+
child.unref();
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
async function main() {
|
|
230
|
+
const opts = parseArgs(process.argv.slice(2));
|
|
231
|
+
const { server, baseUrl } = await createAuthPortalPreviewServer(opts);
|
|
232
|
+
|
|
233
|
+
console.log(`
|
|
234
|
+
Auth portal preview
|
|
235
|
+
───────────────────
|
|
236
|
+
Hub: ${baseUrl}/
|
|
237
|
+
Login: ${baseUrl}/auth/login
|
|
238
|
+
Signup: ${baseUrl}/auth/signup
|
|
239
|
+
Reset: ${baseUrl}/auth/reset
|
|
240
|
+
|
|
241
|
+
Preview login: preview@example.com / preview
|
|
242
|
+
Ctrl+C to stop
|
|
243
|
+
`);
|
|
244
|
+
|
|
245
|
+
if (opts.open) openBrowser(`${baseUrl}/auth/login`);
|
|
246
|
+
|
|
247
|
+
const shutdown = () => {
|
|
248
|
+
server.close(() => process.exit(0));
|
|
249
|
+
};
|
|
250
|
+
process.on('SIGINT', shutdown);
|
|
251
|
+
process.on('SIGTERM', shutdown);
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
const isMain = process.argv[1] && fileURLToPath(import.meta.url) === path.resolve(process.argv[1]);
|
|
255
|
+
if (isMain) {
|
|
256
|
+
main().catch((err) => {
|
|
257
|
+
console.error(err);
|
|
258
|
+
process.exit(1);
|
|
259
|
+
});
|
|
260
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
# InnerAnimalMedia adapter (Sprint 3+)
|
|
2
|
+
|
|
3
|
+
Maps IAM D1 tables (`auth_users`, `accounts`, `account_identities`, `auth_sessions`, …)
|
|
4
|
+
into portable AgentSam Identity contracts.
|
|
5
|
+
|
|
6
|
+
IAM-specific behavior (tenant resolution, workspace membership, OAuth callback wiring)
|
|
7
|
+
stays here — not in `providers/`.
|