Skip to content

Commit a3f9c79

Browse files
elberrdclaude
andauthored
feat: sign-in opcional — guest mode instala harness + FIA sem login (#3)
O login da Academy vira pergunta opcional logo no passo 1: sessão válida segue direto ("Welcome back"); sem login, o guest instala só harness + agente, com alerta claro do que fica travado (templates e toda a automação) no início e no resumo final. - auth.js: oferta "Sign in (optional)" com as duas opções; negação de autorização cai para guest em vez de matar a run (--login avulso ainda sai com erro); assinatura inativa avisa com link de renovação e oferece o caminho limitado; --yes sem token vira guest com warning (CREATE_IAI_TOKEN inválido continua falhando alto no CI). - mode.js: guest + --mode full / --stack recomendada = erro duro (nunca downgrade silencioso em script); interativo esconde a opção template (linha LOCKED no box); resume de full install pela metade exige login. - stack.js: guest não é promovido a full quando as escolhas batem com a stack recomendada — segue pelo manifesto com aviso. - Download: header Authorization só com token; harness.js sem o guard de token (o servidor serve o harness anonimamente — PUBLIC_TEMPLATES no gate do iai-cursos, precisa de deploy do Convex); mensagem amigável para missing_token/401. - Modo harness não instala mais gh (vestigial — nada o usa nesse modo). - README/DOCS/--help atualizados; testes novos (mode-guest + download guest sem header) — 688 passando. Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
1 parent d16593e commit a3f9c79

16 files changed

Lines changed: 366 additions & 112 deletions

DOCS.md

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,9 @@ harness, **FIA — the IAI Agent Factory** and how to extend it. Getting started
1919
| **Template** | private repo (community gated API) | Next.js 16 + Convex + Clerk + shadcn/Tailwind v4 app, with EVERYTHING implemented — **optional** |
2020

2121
The CLI **does not bundle** the template or the harness: both are downloaded at
22-
install time **exclusively through the community gated API** (paying-student
23-
token) — there is no direct GitHub clone.
22+
install time **exclusively through the community API** — there is no direct
23+
GitHub clone. The templates require the paying-student token; the harness is
24+
also served **without** one (guest mode installs harness + FIA only).
2425

2526
**Tenancy**: `--tenancy single` (default) downloads live1; `--tenancy multi`
2627
downloads **live2** — multi-tenant with organizations owned by the
@@ -218,11 +219,11 @@ prelude, then the tail for the chosen mode).
218219

219220
| # | Step | File | Notes |
220221
| -- | ----- | ------- | ----- |
221-
| 1 | Access — community student | `steps/auth.js` | Device-flow login; validates the subscription |
222+
| 1 | Access — sign in (optional) | `steps/auth.js` | Valid session → "Welcome back"; otherwise offers the device-flow login. Declining sets **guest mode**: harness + FIA only, every template path locked (announced on the spot) |
222223
| 2 | Claude Code | `steps/preflight.js` | Blocks if missing/logged out |
223224
| 3 | Name and folder | `steps/project.js` | `.` installs in the current folder |
224-
| 4 | **How to start — mode + stack path** | `steps/mode.js` | Sets `ctx.mode` + `ctx.stackPath` |
225-
| 5 | Your stack — layer by layer | `steps/stack.js` | Only the "build my own stack" path asks; may switch `ctx.mode` to `full` |
225+
| 4 | **How to start — mode + stack path** | `steps/mode.js` | Sets `ctx.mode` + `ctx.stackPath`; in guest mode the template path is locked (flags forcing it error out) |
226+
| 5 | Your stack — layer by layer | `steps/stack.js` | Only the "build my own stack" path asks; may switch `ctx.mode` to `full` (never for guests) |
226227

227228
**`full` mode (harness + template):** each step declares a CAPABILITY
228229
(`core` always runs; `convex`/`clerk`/`shadcn`/`storage`/`mcps` only when the
@@ -257,7 +258,7 @@ template declares them in `requires` — see §2.4 and `src/lib/pipeline.js`).
257258

258259
| # | Step | File | Notes |
259260
| -- | ----- | ------- | ----- |
260-
| 6 | CLIs (git, gh) | `steps/preflight.js` | Binaries only — no gh login and no Vercel; with a community token even the gh install is skipped |
261+
| 6 | CLIs (git) | `steps/preflight.js` | Binaries only — no gh, no Vercel (the harness always comes through the community API, token or not) |
261262
| 7 | Harness | `steps/harness.js` | Merge into the folder; runs `git init` if missing |
262263
| 8 | Stack — manifest, docs and tooling | `steps/stack-docs.js` | Manifest + `AGENTS.md` block + skills/CLIs/MCPs of the chosen techs (incl. Neon/Supabase dev DB) |
263264
| 9 | FIA — Pi + FDAs | `steps/fia.js` | Stamps `imp/` + `.pi/` |
@@ -439,7 +440,8 @@ the browser sends the binary STRAIGHT to storage via signed URL.
439440
## 8. Harness
440441

441442
**The installer's base — always installed**, in both modes. Downloads the
442-
harness through the community gated API (paying-student token — the only path)
443+
harness through the community API (the only path — with the student token, or
444+
anonymously in guest mode: harness + FIA are the free tier)
443445
and merges **without overwriting anything** — existing files
444446
win, the harness `README.md` becomes `imp/HARNESS.md`, and its `AGENTS.md` is
445447
appended to the project's between the `<!-- harness-start/end -->` markers.
@@ -846,7 +848,8 @@ FIA and design
846848
no API key; default on. Requires Node >= 22.12
847849
--no-impeccable Skips Impeccable (--skip-impeccable is the same)
848850
849-
Access (the CLI is exclusive to students with an active subscription)
851+
Access (sign-in is optional: it unlocks the templates + their automation;
852+
without it the installer delivers the harness + agent only)
850853
--login Authenticates this computer (browser) and exits
851854
--logout Removes/revokes the CLI token and exits
852855
--whoami Shows subscription status and exits
@@ -871,6 +874,9 @@ General
871874
`--preset`/groups), default shadcn block, no webhook/R2/deploy, **harness
872875
installed**, local commit without a remote repo, no integration-CLI logins.
873876
For harness only without prompts: `--harness-only` (or `--mode harness`).
877+
Without a valid login (or `CREATE_IAI_TOKEN`), `--yes` continues as **guest**
878+
— harness + agent only — and `--mode full`/`--stack template` error out
879+
instead of silently downgrading.
874880

875881
## 10. How to add a new addon
876882

README.md

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,22 @@ npx impactus
1818

1919
## Who can use it
2020

21-
The installer is exclusive to **[Impactus Academy](https://www.impactus.academy)
22-
students with an active enrollment**. On first run it opens the browser to
23-
authorize your computer (OAuth device flow); the project templates and the
24-
agent harness are delivered by the academy's gated API — they are **not** in
25-
this repository or in the npm package, and the CLI has no clone path. Access
26-
is revalidated on every use.
21+
Anyone can run the installer — **signing in is optional and asked right at
22+
the start**:
23+
24+
- **Signed in** ([Impactus Academy](https://www.impactus.academy) student with
25+
an active enrollment): the full installer — the ready-made project templates
26+
plus the whole automated template pipeline (cloud provisioning, keys,
27+
webhooks, GitHub, deploy).
28+
- **Without signing in** (guest mode): the CLI still installs the **agent
29+
harness + the FIA agents**, but nothing from the templates — the CLI shows
30+
the limitation up front and again in the final summary.
31+
32+
Login uses the OAuth device flow (browser, one time per computer); access is
33+
revalidated on every use. Templates and harness are delivered by the academy's
34+
API — they are **not** in this repository or in the npm package, and the CLI
35+
has no clone path (the harness is served without a token; the templates
36+
require an active enrollment).
2737

2838
```bash
2939
npx impactus --login # authenticate this computer
@@ -56,6 +66,8 @@ command passes straight through to the real `pi` binary.
5666

5767
- **Node.js >= 22.12**
5868
- An **active [Impactus Academy](https://www.impactus.academy) enrollment**
69+
for the templates + automated pipeline (optional: without it the installer
70+
delivers the harness + agent only)
5971
- **Claude Code** installed and logged in with a Claude **Pro/Max**
6072
subscription
6173
- For FIA's Codex roles: a **ChatGPT Plus/Pro** subscription (login at the
@@ -81,5 +93,6 @@ onboarding happen inside the academy community.
8193

8294
[MIT](./LICENSE) — covers this repository: the installer CLI and the runtime
8395
it stamps (`fia-templates/`, `pi-templates/`). The project templates and the
84-
agent harness are proprietary, live in private repositories and are delivered
85-
only to enrolled students — they are not part of this package.
96+
agent harness are proprietary and live in private repositories — they are not
97+
part of this package. The templates are delivered only to enrolled students;
98+
the harness is served by the academy's API to any installer run.

src/config.js

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,14 @@
11
// Central configuration for the impactus installer.
22

3-
// ── Community (paid-student gate via device flow) ────────────────────────────
4-
// The CLI only installs for students with an ACTIVE subscription in the
5-
// community. Login uses the OAuth 2.0 Device Authorization Grant (RFC 8628)
6-
// against the /api/cli/* endpoints served by the community's Convex deployment
7-
// (.convex.site); both the template AND the private harness are downloaded
8-
// through it (tarball) — the student never needs GitHub access, and the CLI
9-
// has no direct-clone path.
3+
// ── Community (student gate via device flow — sign-in is OPTIONAL) ───────────
4+
// Signing in (ACTIVE subscription) unlocks the full installer; without it the
5+
// CLI still delivers the harness + FIA ("guest mode" — steps/auth.js) but
6+
// nothing from the templates. Login uses the OAuth 2.0 Device Authorization
7+
// Grant (RFC 8628) against the /api/cli/* endpoints served by the community's
8+
// Convex deployment (.convex.site); template AND harness are downloaded
9+
// through it (tarball) — the harness even without a token, the templates only
10+
// with one. The student never needs GitHub access, and the CLI has no
11+
// direct-clone path.
1012
//
1113
// `apiBase` must point to the community's PRODUCTION deployment — the same one
1214
// the www.impactus.academy site uses (verified against the production bundle).
@@ -75,8 +77,9 @@ export const DEFAULT_TEMPLATE_ID = 'live1';
7577

7678
// Harness — optional agent-workflow scaffold (/start, /dev, /sv, /test-ui, …)
7779
// merged INTO the generated project as the last install step. Private
78-
// repository, downloaded EXCLUSIVELY through the community's gated API
79-
// (paid-student token) — there is no direct GitHub clone.
80+
// repository, downloaded EXCLUSIVELY through the community's API — served
81+
// even WITHOUT a token (the free tier: guests install harness + FIA); there
82+
// is no direct GitHub clone.
8083
// Merge rules (see src/steps/harness.js):
8184
// - files that already exist in the project are NEVER overwritten;
8285
// - the harness README.md is saved as imp/HARNESS.md (the project README wins);

src/lib/args.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -307,7 +307,8 @@ Options:
307307
--terminal, --no-ui Accepted for compatibility (the terminal is already the default)
308308
--port <n> UI server port (default: 4599)
309309
310-
Access (the CLI is exclusive to community students with an active subscription):
310+
Access (sign-in is optional: it unlocks the templates + their automation;
311+
without it the installer delivers the harness + agent only):
311312
--login Authenticates this computer (opens the browser) and exits
312313
--logout Removes/revokes this computer's CLI token and exits
313314
--whoami Shows your subscription status and exits

src/lib/auth-client.js

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,9 @@ export async function revokeToken(apiBase, token, timeoutMs = 10000) {
123123
}
124124

125125
/**
126-
* Downloads the private (gated) template tarball. Writes to `destPath`.
126+
* Downloads a template tarball through the community API. Writes to `destPath`.
127+
* `token` may be null: the harness is served without one (the free tier) —
128+
* the gated names (live1/live2) answer 401/missing_token instead.
127129
* Capped at 2 minutes so a frozen connection never hangs the install forever;
128130
* on timeout the reason is `download_timeout`, and any other network failure
129131
* (DNS, refused, offline) is `network_error` — never a raw throw
@@ -136,7 +138,7 @@ export async function downloadTemplate(apiBase, token, name, destPath, ref, time
136138
const signal = AbortSignal.timeout(timeoutMs); // also aborts the body read
137139
try {
138140
const res = await fetch(`${apiBase}/api/cli/template/${encodeURIComponent(name)}${qs}`, {
139-
headers: { authorization: `Bearer ${token}` },
141+
headers: token ? { authorization: `Bearer ${token}` } : {},
140142
signal,
141143
});
142144
if (!res.ok) {

src/lib/pipeline.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,9 +34,9 @@ export function unknownCapabilities(requires = []) {
3434
* Used in harness mode (which has no decisions phase). In full mode the
3535
* preflight now looks at the DECISION (ctx.decisions.push/deploy) — gh/vercel
3636
* are only prepared when the user said "yes". GitHub CLI login is only
37-
* needed when a push can happen: with a student token, both the template
38-
* and the harness come through the gate (steps/harness.js uses the API
39-
* whenever `ctx.authToken` exists; `gh` is only a dev fallback without a token).
37+
* needed when a push can happen: template and harness always come through
38+
* the community API (the harness even without a token — guest mode), so
39+
* harness mode never touches `gh` at all.
4040
*
4141
* Mirrors the precedence of steps/github.js.
4242
*/

src/lib/template-fetch.js

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,9 @@ export async function fetchTemplateToDir(apiBase, token, name, destDir, ref) {
4343
* matters is between "wait and try again" and "retrying won't help":
4444
*
4545
* no_active_enrollment → inactive subscription, it's on the student;
46+
* missing_token / http_401 → the download needs the sign-in (a guest run
47+
* reached a gated name, or the server does not serve this one anonymously
48+
* yet) — retrying won't help, signing in will;
4649
* server_misconfigured → missing env on the community server (e.g. the
4750
* GitHub token that fetches the private repos). Saying "try again in a
4851
* moment" here makes the student retry forever an error only the
@@ -63,6 +66,13 @@ export function downloadErrorMessage(what, reason) {
6366
if (reason === 'no_active_enrollment') {
6467
return `Your subscription is no longer active — the ${what} could not be downloaded.`;
6568
}
69+
if (reason === 'missing_token' || reason === 'http_401') {
70+
return [
71+
`The ${what} download requires the community sign-in.`,
72+
'Authenticate with `npx impactus --login` (or run the installer again and',
73+
'choose "Sign in") and repeat the command.',
74+
].join('\n');
75+
}
6676
if (reason === 'server_misconfigured') {
6777
return [
6878
`The community server couldn't deliver the ${what} (pending configuration on its side).`,

src/main.js

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -44,8 +44,10 @@ export async function main(flags = {}) {
4444

4545
// Early gate (before login): if --template-id/--tenancy ask for an unknown
4646
// or unpublished template, warn right away. Every download (template AND
47-
// harness) goes exclusively through the community's gated API — there is no
48-
// direct GitHub clone (see steps/project.js and steps/harness.js).
47+
// harness) goes exclusively through the community's API — there is no
48+
// direct GitHub clone. The templates require the student token; the harness
49+
// is also served WITHOUT one (guest mode installs harness + FIA only — see
50+
// steps/auth.js, steps/mode.js and steps/harness.js).
4951
{
5052
const { id } = resolveTemplateId(flags);
5153
if (id && !TEMPLATES[id]) {
@@ -92,7 +94,7 @@ export async function main(flags = {}) {
9294
// template stack runs before it; in 'harness' mode nothing else runs — only
9395
// the folder is prepared and the harness is merged into it.
9496
const preludeSteps = [
95-
['Access — community student', () => ensureAuthenticated(ctx)],
97+
['Access — sign in to the community (optional)', () => ensureAuthenticated(ctx)],
9698
['Prerequisite: Claude Code', () => ensureClaudeCode(flags)],
9799
['Project — target folder (the project name is the folder name)', async () => Object.assign(ctx, await promptProject(flags))],
98100
['How to start — ready-made template, your own stack, or decide later', () => selectInstallMode(ctx)],
@@ -163,14 +165,13 @@ export async function main(flags = {}) {
163165
const tailSteps = (mode) =>
164166
mode === 'harness'
165167
? [
166-
// The harness comes through the community gate (no clone): git comes
167-
// in for the local commit and nothing is pushed to GitHub, so with a
168-
// community token the gh binary would never be used — skip installing
169-
// it. Without a token (dev runs outside the gate) gh stays as the
170-
// fallback. Vercel CLI is not installed.
168+
// The harness always comes through the community API (with or
169+
// without a token — guests get it anonymously): git comes in for the
170+
// local commit, nothing is pushed to GitHub and no clone happens, so
171+
// neither gh nor the Vercel CLI is installed.
171172
[
172-
'CLIs — git and gh',
173-
() => ensureCliTools({ vercel: false, gh: !ctx.authToken, ghAuth: false, flags }),
173+
'CLIs — git',
174+
() => ensureCliTools({ vercel: false, gh: false, ghAuth: false, flags }),
174175
],
175176
['Harness — agent workflow', () => setupHarness(ctx)],
176177
// After the harness (which creates ai-docs/): the ai-docs/stack.md

0 commit comments

Comments
 (0)