@ritualai/cli 0.3.0 → 0.3.2
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/README.md +21 -7
- package/dist/commands/init.js +87 -14
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/login.js +13 -31
- package/dist/commands/login.js.map +1 -1
- package/dist/index.js +5 -1
- package/dist/index.js.map +1 -1
- package/dist/lib/auth-flow.js +62 -0
- package/dist/lib/auth-flow.js.map +1 -0
- package/dist/lib/prompt.js +35 -0
- package/dist/lib/prompt.js.map +1 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -13,19 +13,33 @@ npm install -g @ritualai/cli
|
|
|
13
13
|
## Quick start
|
|
14
14
|
|
|
15
15
|
```bash
|
|
16
|
-
ritual login # browser-based sign-in (OAuth 2.1 + PKCE)
|
|
17
16
|
ritual init # scaffold skills + register MCP with every detected agent
|
|
17
|
+
# (prompts to open browser for sign-in on first run)
|
|
18
18
|
ritual doctor # sanity-check the environment
|
|
19
19
|
```
|
|
20
20
|
|
|
21
|
-
That's it. `init`
|
|
21
|
+
That's it — one command. On first run, `init` detects you're not signed
|
|
22
|
+
in and prompts:
|
|
22
23
|
|
|
23
|
-
|
|
24
|
+
```
|
|
25
|
+
You are not signed in.
|
|
26
|
+
Press Enter to sign in (opens browser), or Ctrl-C to abort:
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
Hit Enter, complete the browser OAuth flow, and `init` resumes
|
|
30
|
+
automatically. Subsequent `init` runs skip the prompt (credentials are
|
|
31
|
+
cached and refreshed automatically).
|
|
32
|
+
|
|
33
|
+
`init` does four things:
|
|
34
|
+
|
|
35
|
+
1. **Signs you in** if you aren't already (browser OAuth, npm-style
|
|
36
|
+
"press Enter to open browser" prompt). Skipped if already signed in.
|
|
37
|
+
2. **Detects** which AI coding agents you have installed (Claude Code,
|
|
24
38
|
Cursor, Windsurf, Kiro, Gemini CLI, VS Code / Copilot, Codex).
|
|
25
|
-
|
|
39
|
+
3. **Mints a long-lived Personal Access Token** via the Ritual API
|
|
26
40
|
named `Ritual CLI — <hostname>`, so the agent has a credential
|
|
27
41
|
that doesn't expire every 5 minutes the way OAuth tokens do.
|
|
28
|
-
|
|
42
|
+
4. **For each detected agent:** copies the Ritual skill files into your
|
|
29
43
|
project (`.claude/skills/`, `.cursor/rules/`, etc.) AND writes
|
|
30
44
|
the MCP server config (`claude mcp add-json` for Claude Code, or
|
|
31
45
|
`mcp.json` merge for the others) with the PAT as the Bearer.
|
|
@@ -36,8 +50,8 @@ then try `/ritual build <feature>` from inside the agent.
|
|
|
36
50
|
## Commands
|
|
37
51
|
|
|
38
52
|
```bash
|
|
39
|
-
ritual init [--agent <id>] [--list] # scaffold + register
|
|
40
|
-
ritual login # browser sign-in
|
|
53
|
+
ritual init [--agent <id>] [--list] # scaffold + register (signs in if needed)
|
|
54
|
+
ritual login # explicit browser sign-in
|
|
41
55
|
ritual logout # clear creds
|
|
42
56
|
ritual whoami # session info, auto-refresh
|
|
43
57
|
ritual refresh # force token refresh
|
package/dist/commands/init.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.DEV_ISSUER = void 0;
|
|
3
4
|
exports.initCommand = initCommand;
|
|
4
5
|
const config_1 = require("../lib/config");
|
|
5
6
|
const api_client_1 = require("../lib/api-client");
|
|
@@ -8,6 +9,32 @@ const detector_1 = require("../lib/agents/detector");
|
|
|
8
9
|
const providers_1 = require("../lib/agents/providers");
|
|
9
10
|
const configure_mcp_1 = require("../lib/agents/configure-mcp");
|
|
10
11
|
const skill_copy_1 = require("../lib/skill-copy");
|
|
12
|
+
const auth_flow_1 = require("../lib/auth-flow");
|
|
13
|
+
const prompt_1 = require("../lib/prompt");
|
|
14
|
+
/**
|
|
15
|
+
* Issuer URL for the dev shortcut. Exported so `ritual login --dev`
|
|
16
|
+
* can use the same constant (single source of truth — if we ever flip
|
|
17
|
+
* the dev domain, one place to update).
|
|
18
|
+
*/
|
|
19
|
+
exports.DEV_ISSUER = 'https://auth.dev.ritualapp.cloud/realms/ritual';
|
|
20
|
+
/**
|
|
21
|
+
* Resolve the OIDC issuer to use for lazy-auth in this `init` run.
|
|
22
|
+
*
|
|
23
|
+
* 1. --dev (highest priority — explicit shortcut for the Ritual team)
|
|
24
|
+
* 2. --issuer (explicit URL for self-hosted enterprise)
|
|
25
|
+
* 3. RITUAL_KEYCLOAK_URL env var (covered inside runBrowserLoginAndSave)
|
|
26
|
+
* 4. Default (prod)
|
|
27
|
+
*
|
|
28
|
+
* Step 3+ are handled by `runBrowserLoginAndSave` if we pass undefined
|
|
29
|
+
* — so we only need to return a string for #1 and #2.
|
|
30
|
+
*/
|
|
31
|
+
function resolveIssuerForInit(opts) {
|
|
32
|
+
if (opts.dev)
|
|
33
|
+
return exports.DEV_ISSUER;
|
|
34
|
+
if (opts.issuer)
|
|
35
|
+
return opts.issuer;
|
|
36
|
+
return undefined; // let auth-flow.ts pick from env / default
|
|
37
|
+
}
|
|
11
38
|
async function initCommand(opts = {}) {
|
|
12
39
|
console.log('');
|
|
13
40
|
console.log(' Ritual — scaffolding skills + connecting AI coding agents');
|
|
@@ -21,20 +48,62 @@ async function initCommand(opts = {}) {
|
|
|
21
48
|
console.log('');
|
|
22
49
|
return;
|
|
23
50
|
}
|
|
24
|
-
// --- 1. Auth check
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
51
|
+
// --- 1. Auth check (lazy login — npm-style "press Enter to sign in") ---
|
|
52
|
+
//
|
|
53
|
+
// If we're signed in, fast-path: continue.
|
|
54
|
+
// If we're not (or session is dead), and stdin is a TTY, prompt to
|
|
55
|
+
// open the browser inline so `init` is a one-command experience.
|
|
56
|
+
// If stdin is non-TTY (CI / piped), keep the old behavior: clear
|
|
57
|
+
// error + non-zero exit. Unattended runs MUST NOT hang waiting
|
|
58
|
+
// for an Enter that's never coming.
|
|
59
|
+
let tokenStatus = await (0, config_1.getValidAccessToken)();
|
|
60
|
+
if (tokenStatus.kind !== 'signed-in') {
|
|
61
|
+
const reason = tokenStatus.kind === 're-auth-required'
|
|
62
|
+
? `session expired (${tokenStatus.reason})`
|
|
63
|
+
: 'you are not signed in';
|
|
64
|
+
if (!process.stdin.isTTY) {
|
|
65
|
+
console.error(` ✗ ${reason}. Run \`ritual login\` first, then \`ritual init\`.`);
|
|
66
|
+
console.error('');
|
|
67
|
+
process.exitCode = 1;
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
70
|
+
console.log(` ${capitalize(reason)}.`);
|
|
71
|
+
try {
|
|
72
|
+
await (0, prompt_1.prompt)(' Press Enter to sign in (opens browser), or Ctrl-C to abort: ');
|
|
73
|
+
}
|
|
74
|
+
catch {
|
|
75
|
+
// Ctrl-D / stdin closed mid-prompt — treat as abort.
|
|
76
|
+
console.log('');
|
|
77
|
+
console.log(' Sign-in aborted.');
|
|
78
|
+
process.exitCode = 1;
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
try {
|
|
82
|
+
await (0, auth_flow_1.runBrowserLoginAndSave)({
|
|
83
|
+
issuer: resolveIssuerForInit(opts),
|
|
84
|
+
clientId: opts.clientId,
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
catch (err) {
|
|
88
|
+
console.error('');
|
|
89
|
+
console.error(` ✗ Sign-in did not complete: ${err.message}`);
|
|
90
|
+
console.error(' Run `ritual login` to retry, then re-run `ritual init`.');
|
|
91
|
+
console.error('');
|
|
92
|
+
process.exitCode = 1;
|
|
93
|
+
return;
|
|
94
|
+
}
|
|
95
|
+
// Re-read credentials now that login succeeded. We use this to
|
|
96
|
+
// hand the OAuth access token to mintAgentPat below.
|
|
97
|
+
tokenStatus = await (0, config_1.getValidAccessToken)();
|
|
98
|
+
if (tokenStatus.kind !== 'signed-in') {
|
|
99
|
+
// Should never happen — login just succeeded and saved tokens.
|
|
100
|
+
console.error(' ✗ Sign-in succeeded but credentials still unreadable. Please re-run.');
|
|
101
|
+
process.exitCode = 1;
|
|
102
|
+
return;
|
|
103
|
+
}
|
|
104
|
+
console.log('');
|
|
105
|
+
console.log(` ✓ Signed in as ${tokenStatus.creds.user?.email ?? tokenStatus.creds.user?.sub ?? 'unknown'}`);
|
|
106
|
+
console.log('');
|
|
38
107
|
}
|
|
39
108
|
// --- 2. Detect agents (or pick a specific one) -------------------
|
|
40
109
|
let targets;
|
|
@@ -133,6 +202,10 @@ async function initCommand(opts = {}) {
|
|
|
133
202
|
console.log(' In your agent, try: /ritual build <feature>');
|
|
134
203
|
console.log('');
|
|
135
204
|
}
|
|
205
|
+
/** Tiny helper for the lazy-auth message ("you are not signed in" → "You are..."). */
|
|
206
|
+
function capitalize(s) {
|
|
207
|
+
return s.length === 0 ? s : s[0].toUpperCase() + s.slice(1);
|
|
208
|
+
}
|
|
136
209
|
/**
|
|
137
210
|
* Mirror of `apiBaseFromIssuer` but for the web app. Used in the
|
|
138
211
|
* "manage tokens at <url>" hint above.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"init.js","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"init.js","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"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"}
|
package/dist/commands/login.js
CHANGED
|
@@ -1,15 +1,8 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
-
};
|
|
5
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
3
|
exports.loginCommand = loginCommand;
|
|
7
|
-
const
|
|
8
|
-
const
|
|
9
|
-
const config_1 = require("../lib/config");
|
|
10
|
-
const DEFAULT_ISSUER = process.env.RITUAL_KEYCLOAK_URL ?? 'https://auth.ritualapp.cloud/realms/ritual';
|
|
11
|
-
const DEFAULT_CLIENT_ID = process.env.RITUAL_KEYCLOAK_CLIENT_ID ?? 'ritual-cli';
|
|
12
|
-
const DEFAULT_SCOPE = 'openid profile email ritual:read ritual:write';
|
|
4
|
+
const auth_flow_1 = require("../lib/auth-flow");
|
|
5
|
+
const init_1 = require("./init");
|
|
13
6
|
/**
|
|
14
7
|
* `ritual login` — browser-based Auth Code + PKCE flow against
|
|
15
8
|
* Keycloak. On success, stores the access + refresh tokens in
|
|
@@ -17,17 +10,23 @@ const DEFAULT_SCOPE = 'openid profile email ritual:read ritual:write';
|
|
|
17
10
|
*
|
|
18
11
|
* Defaults point at production (`auth.ritualapp.cloud`); override via
|
|
19
12
|
* `--issuer https://auth.dev.ritualapp.cloud/realms/ritual` for dev,
|
|
20
|
-
* or set `RITUAL_KEYCLOAK_URL` env var.
|
|
13
|
+
* `--dev` as the shortcut, or set `RITUAL_KEYCLOAK_URL` env var.
|
|
14
|
+
*
|
|
15
|
+
* The flow itself lives in `lib/auth-flow.ts` so `ritual init` can
|
|
16
|
+
* invoke the same path when it lazily prompts the user to sign in.
|
|
21
17
|
*/
|
|
22
18
|
async function loginCommand(options) {
|
|
23
|
-
const issuer = options.issuer ?? DEFAULT_ISSUER;
|
|
24
|
-
const clientId = options.clientId ?? DEFAULT_CLIENT_ID;
|
|
25
19
|
console.log('');
|
|
26
20
|
console.log(' Ritual — sign in');
|
|
27
21
|
console.log('');
|
|
28
|
-
|
|
22
|
+
// --dev wins over --issuer (consistent with init); both win over env.
|
|
23
|
+
const issuer = options.dev ? init_1.DEV_ISSUER : options.issuer;
|
|
24
|
+
let creds;
|
|
29
25
|
try {
|
|
30
|
-
|
|
26
|
+
creds = await (0, auth_flow_1.runBrowserLoginAndSave)({
|
|
27
|
+
issuer,
|
|
28
|
+
clientId: options.clientId,
|
|
29
|
+
});
|
|
31
30
|
}
|
|
32
31
|
catch (err) {
|
|
33
32
|
console.error('');
|
|
@@ -35,23 +34,6 @@ async function loginCommand(options) {
|
|
|
35
34
|
process.exitCode = 1;
|
|
36
35
|
return;
|
|
37
36
|
}
|
|
38
|
-
const claims = (0, oidc_1.decodeJwtPayloadUnsafe)(tokenSet.access_token);
|
|
39
|
-
const creds = {
|
|
40
|
-
version: 1,
|
|
41
|
-
issuer,
|
|
42
|
-
clientId,
|
|
43
|
-
tokenSet: {
|
|
44
|
-
access_token: tokenSet.access_token,
|
|
45
|
-
refresh_token: tokenSet.refresh_token,
|
|
46
|
-
expires_at: Math.floor(Date.now() / 1000) + tokenSet.expires_in,
|
|
47
|
-
id_token: tokenSet.id_token,
|
|
48
|
-
scope: tokenSet.scope,
|
|
49
|
-
},
|
|
50
|
-
user: claims
|
|
51
|
-
? { sub: claims.sub, email: claims.email ?? claims.preferred_username }
|
|
52
|
-
: undefined,
|
|
53
|
-
};
|
|
54
|
-
(0, config_1.saveCredentials)(creds);
|
|
55
37
|
const display = creds.user?.email ?? creds.user?.sub ?? 'unknown';
|
|
56
38
|
console.log('');
|
|
57
39
|
console.log(` ✓ Signed in as ${display}`);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"login.js","sourceRoot":"","sources":["../../src/commands/login.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"login.js","sourceRoot":"","sources":["../../src/commands/login.ts"],"names":[],"mappings":";;AAwBA,oCA4BC;AApDD,gDAA0D;AAC1D,iCAAoC;AAWpC;;;;;;;;;;;GAWG;AACI,KAAK,UAAU,YAAY,CAAC,OAAqB;IACvD,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAChB,OAAO,CAAC,GAAG,CAAC,oBAAoB,CAAC,CAAC;IAClC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAEhB,sEAAsE;IACtE,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,iBAAU,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC;IAEzD,IAAI,KAAK,CAAC;IACV,IAAI,CAAC;QACJ,KAAK,GAAG,MAAM,IAAA,kCAAsB,EAAC;YACpC,MAAM;YACN,QAAQ,EAAE,OAAO,CAAC,QAAQ;SAC1B,CAAC,CAAC;IACJ,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACd,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;QAClB,OAAO,CAAC,KAAK,CAAC,qBAAsB,GAAa,CAAC,OAAO,EAAE,CAAC,CAAC;QAC7D,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;QACrB,OAAO;IACR,CAAC;IAED,MAAM,OAAO,GAAG,KAAK,CAAC,IAAI,EAAE,KAAK,IAAI,KAAK,CAAC,IAAI,EAAE,GAAG,IAAI,SAAS,CAAC;IAClE,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAChB,OAAO,CAAC,GAAG,CAAC,oBAAoB,OAAO,EAAE,CAAC,CAAC;IAC3C,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAChB,OAAO,CAAC,GAAG,CAAC,2DAA2D,CAAC,CAAC;IACzE,OAAO,CAAC,GAAG,CAAC,mDAAmD,CAAC,CAAC;IACjE,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;AACjB,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -13,7 +13,7 @@ program
|
|
|
13
13
|
.name('ritual')
|
|
14
14
|
.description('Ritual CLI — connect AI coding agents to Ritual Cloud. ' +
|
|
15
15
|
'Scaffold skills, register MCP servers, manage sessions.')
|
|
16
|
-
.version('0.3.
|
|
16
|
+
.version('0.3.2');
|
|
17
17
|
// `init` is the headline command: scaffold + register against every
|
|
18
18
|
// detected agent. Listed first so `ritual --help` surfaces it.
|
|
19
19
|
program
|
|
@@ -21,12 +21,16 @@ program
|
|
|
21
21
|
.description('Scaffold Ritual skills + register MCP server with every detected AI coding agent')
|
|
22
22
|
.option('--agent <id>', 'Restrict to one agent (e.g. claude-code, cursor, kiro)')
|
|
23
23
|
.option('--list', 'List known agents and exit')
|
|
24
|
+
.option('--issuer <url>', 'OIDC issuer for the lazy-auth flow (defaults to prod or RITUAL_KEYCLOAK_URL env)')
|
|
25
|
+
.option('--client-id <id>', 'OIDC client id (defaults to "ritual-cli")')
|
|
26
|
+
.option('--dev', '[internal] shortcut for --issuer https://auth.dev.ritualapp.cloud/realms/ritual')
|
|
24
27
|
.action(init_1.initCommand);
|
|
25
28
|
program
|
|
26
29
|
.command('login')
|
|
27
30
|
.description('Authenticate with Ritual via your browser')
|
|
28
31
|
.option('--issuer <url>', 'OIDC issuer (defaults to https://auth.ritualapp.cloud/realms/ritual or RITUAL_KEYCLOAK_URL env)')
|
|
29
32
|
.option('--client-id <id>', 'OIDC client id (defaults to "ritual-cli" or RITUAL_KEYCLOAK_CLIENT_ID env)')
|
|
33
|
+
.option('--dev', '[internal] shortcut for --issuer https://auth.dev.ritualapp.cloud/realms/ritual')
|
|
30
34
|
.action(login_1.loginCommand);
|
|
31
35
|
program
|
|
32
36
|
.command('logout')
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;AAEA,yCAAoC;AACpC,4CAAgD;AAChD,8CAAkD;AAClD,8CAAkD;AAClD,gDAAoD;AACpD,0CAA8C;AAC9C,8CAAkD;AAElD,MAAM,OAAO,GAAG,IAAI,mBAAO,EAAE,CAAC;AAE9B,OAAO;KACL,IAAI,CAAC,QAAQ,CAAC;KACd,WAAW,CACX,yDAAyD;IACxD,yDAAyD,CAC1D;KACA,OAAO,CAAC,OAAO,CAAC,CAAC;AAEnB,oEAAoE;AACpE,+DAA+D;AAC/D,OAAO;KACL,OAAO,CAAC,MAAM,CAAC;KACf,WAAW,CAAC,kFAAkF,CAAC;KAC/F,MAAM,CAAC,cAAc,EAAE,wDAAwD,CAAC;KAChF,MAAM,CAAC,QAAQ,EAAE,4BAA4B,CAAC;KAC9C,MAAM,CAAC,kBAAW,CAAC,CAAC;AAEtB,OAAO;KACL,OAAO,CAAC,OAAO,CAAC;KAChB,WAAW,CAAC,2CAA2C,CAAC;KACxD,MAAM,CACN,gBAAgB,EAChB,iGAAiG,CACjG;KACA,MAAM,CACN,kBAAkB,EAClB,4EAA4E,CAC5E;KACA,MAAM,CAAC,oBAAY,CAAC,CAAC;AAEvB,OAAO;KACL,OAAO,CAAC,QAAQ,CAAC;KACjB,WAAW,CAAC,yBAAyB,CAAC;KACtC,MAAM,CAAC,sBAAa,CAAC,CAAC;AAExB,OAAO;KACL,OAAO,CAAC,QAAQ,CAAC;KACjB,WAAW,CAAC,6DAA6D,CAAC;KAC1E,MAAM,CAAC,sBAAa,CAAC,CAAC;AAExB,OAAO;KACL,OAAO,CAAC,SAAS,CAAC;KAClB,WAAW,CAAC,sEAAsE,CAAC;KACnF,MAAM,CAAC,wBAAc,CAAC,CAAC;AAEzB,OAAO;KACL,OAAO,CAAC,QAAQ,CAAC;KACjB,WAAW,CAAC,2EAA2E,CAAC;KACxF,MAAM,CAAC,sBAAa,CAAC,CAAC;AAExB,OAAO,CAAC,UAAU,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,GAAU,EAAE,EAAE;IACrD,OAAO,CAAC,KAAK,CAAC,SAAS,GAAG,CAAC,OAAO,IAAI,CAAC,CAAC;IACxC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AACjB,CAAC,CAAC,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;AAEA,yCAAoC;AACpC,4CAAgD;AAChD,8CAAkD;AAClD,8CAAkD;AAClD,gDAAoD;AACpD,0CAA8C;AAC9C,8CAAkD;AAElD,MAAM,OAAO,GAAG,IAAI,mBAAO,EAAE,CAAC;AAE9B,OAAO;KACL,IAAI,CAAC,QAAQ,CAAC;KACd,WAAW,CACX,yDAAyD;IACxD,yDAAyD,CAC1D;KACA,OAAO,CAAC,OAAO,CAAC,CAAC;AAEnB,oEAAoE;AACpE,+DAA+D;AAC/D,OAAO;KACL,OAAO,CAAC,MAAM,CAAC;KACf,WAAW,CAAC,kFAAkF,CAAC;KAC/F,MAAM,CAAC,cAAc,EAAE,wDAAwD,CAAC;KAChF,MAAM,CAAC,QAAQ,EAAE,4BAA4B,CAAC;KAC9C,MAAM,CACN,gBAAgB,EAChB,kFAAkF,CAClF;KACA,MAAM,CAAC,kBAAkB,EAAE,2CAA2C,CAAC;KACvE,MAAM,CAAC,OAAO,EAAE,iFAAiF,CAAC;KAClG,MAAM,CAAC,kBAAW,CAAC,CAAC;AAEtB,OAAO;KACL,OAAO,CAAC,OAAO,CAAC;KAChB,WAAW,CAAC,2CAA2C,CAAC;KACxD,MAAM,CACN,gBAAgB,EAChB,iGAAiG,CACjG;KACA,MAAM,CACN,kBAAkB,EAClB,4EAA4E,CAC5E;KACA,MAAM,CAAC,OAAO,EAAE,iFAAiF,CAAC;KAClG,MAAM,CAAC,oBAAY,CAAC,CAAC;AAEvB,OAAO;KACL,OAAO,CAAC,QAAQ,CAAC;KACjB,WAAW,CAAC,yBAAyB,CAAC;KACtC,MAAM,CAAC,sBAAa,CAAC,CAAC;AAExB,OAAO;KACL,OAAO,CAAC,QAAQ,CAAC;KACjB,WAAW,CAAC,6DAA6D,CAAC;KAC1E,MAAM,CAAC,sBAAa,CAAC,CAAC;AAExB,OAAO;KACL,OAAO,CAAC,SAAS,CAAC;KAClB,WAAW,CAAC,sEAAsE,CAAC;KACnF,MAAM,CAAC,wBAAc,CAAC,CAAC;AAEzB,OAAO;KACL,OAAO,CAAC,QAAQ,CAAC;KACjB,WAAW,CAAC,2EAA2E,CAAC;KACxF,MAAM,CAAC,sBAAa,CAAC,CAAC;AAExB,OAAO,CAAC,UAAU,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,GAAU,EAAE,EAAE;IACrD,OAAO,CAAC,KAAK,CAAC,SAAS,GAAG,CAAC,OAAO,IAAI,CAAC,CAAC;IACxC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AACjB,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.DEFAULT_SCOPE = exports.DEFAULT_CLIENT_ID = exports.DEFAULT_ISSUER = void 0;
|
|
7
|
+
exports.runBrowserLoginAndSave = runBrowserLoginAndSave;
|
|
8
|
+
const open_1 = __importDefault(require("open"));
|
|
9
|
+
const oidc_1 = require("./oidc");
|
|
10
|
+
const config_1 = require("./config");
|
|
11
|
+
/**
|
|
12
|
+
* Shared OAuth defaults + the "run the browser flow and save tokens"
|
|
13
|
+
* helper. Both `ritual login` and `ritual init`'s lazy-auth path use
|
|
14
|
+
* this so the auth surface stays in one place.
|
|
15
|
+
*
|
|
16
|
+
* If you find yourself wanting a third caller, add it here — don't
|
|
17
|
+
* inline `performLoginFlow` in another command file; the
|
|
18
|
+
* decode-JWT → build CliCredentials → save lockstep is easy to miss
|
|
19
|
+
* a step on.
|
|
20
|
+
*/
|
|
21
|
+
exports.DEFAULT_ISSUER = process.env.RITUAL_KEYCLOAK_URL ?? 'https://auth.ritualapp.cloud/realms/ritual';
|
|
22
|
+
exports.DEFAULT_CLIENT_ID = process.env.RITUAL_KEYCLOAK_CLIENT_ID ?? 'ritual-cli';
|
|
23
|
+
exports.DEFAULT_SCOPE = 'openid profile email ritual:read ritual:write';
|
|
24
|
+
/**
|
|
25
|
+
* Run the browser-based OAuth Auth-Code + PKCE flow, decode the
|
|
26
|
+
* resulting JWT to pull out the user identity, and persist the
|
|
27
|
+
* credentials to `~/.config/ritual/credentials.json`.
|
|
28
|
+
*
|
|
29
|
+
* Returns the saved credentials. Callers can use that to immediately
|
|
30
|
+
* call API endpoints without re-reading from disk.
|
|
31
|
+
*
|
|
32
|
+
* Throws on any failure (user dismissed the browser flow, network
|
|
33
|
+
* error, refused at IdP). The caller decides how to surface that —
|
|
34
|
+
* `ritual login` prints to stderr and sets exit code; `ritual init`
|
|
35
|
+
* prints a clearer "sign-in didn't complete" hint and continues to
|
|
36
|
+
* skip the registration step.
|
|
37
|
+
*/
|
|
38
|
+
async function runBrowserLoginAndSave(opts = {}) {
|
|
39
|
+
const issuer = opts.issuer ?? exports.DEFAULT_ISSUER;
|
|
40
|
+
const clientId = opts.clientId ?? exports.DEFAULT_CLIENT_ID;
|
|
41
|
+
const onMessage = opts.onMessage ?? ((msg) => console.log(` ${msg}`));
|
|
42
|
+
const tokenSet = await (0, oidc_1.performLoginFlow)({ issuer, clientId, scope: exports.DEFAULT_SCOPE }, (url) => (0, open_1.default)(url), onMessage);
|
|
43
|
+
const claims = (0, oidc_1.decodeJwtPayloadUnsafe)(tokenSet.access_token);
|
|
44
|
+
const creds = {
|
|
45
|
+
version: 1,
|
|
46
|
+
issuer,
|
|
47
|
+
clientId,
|
|
48
|
+
tokenSet: {
|
|
49
|
+
access_token: tokenSet.access_token,
|
|
50
|
+
refresh_token: tokenSet.refresh_token,
|
|
51
|
+
expires_at: Math.floor(Date.now() / 1000) + tokenSet.expires_in,
|
|
52
|
+
id_token: tokenSet.id_token,
|
|
53
|
+
scope: tokenSet.scope,
|
|
54
|
+
},
|
|
55
|
+
user: claims
|
|
56
|
+
? { sub: claims.sub, email: claims.email ?? claims.preferred_username }
|
|
57
|
+
: undefined,
|
|
58
|
+
};
|
|
59
|
+
(0, config_1.saveCredentials)(creds);
|
|
60
|
+
return creds;
|
|
61
|
+
}
|
|
62
|
+
//# sourceMappingURL=auth-flow.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auth-flow.js","sourceRoot":"","sources":["../../src/lib/auth-flow.ts"],"names":[],"mappings":";;;;;;AA8CA,wDAoCC;AAlFD,gDAAwB;AACxB,iCAAkE;AAClE,qCAAgE;AAEhE;;;;;;;;;GASG;AAEU,QAAA,cAAc,GAC1B,OAAO,CAAC,GAAG,CAAC,mBAAmB,IAAI,4CAA4C,CAAC;AACpE,QAAA,iBAAiB,GAAG,OAAO,CAAC,GAAG,CAAC,yBAAyB,IAAI,YAAY,CAAC;AAC1E,QAAA,aAAa,GAAG,+CAA+C,CAAC;AAc7E;;;;;;;;;;;;;GAaG;AACI,KAAK,UAAU,sBAAsB,CAC3C,OAA4B,EAAE;IAE9B,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,IAAI,sBAAc,CAAC;IAC7C,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,IAAI,yBAAiB,CAAC;IACpD,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,IAAI,CAAC,CAAC,GAAW,EAAE,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,GAAG,EAAE,CAAC,CAAC,CAAC;IAE/E,MAAM,QAAQ,GAAG,MAAM,IAAA,uBAAgB,EACtC,EAAE,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE,qBAAa,EAAE,EAC1C,CAAC,GAAG,EAAE,EAAE,CAAC,IAAA,cAAI,EAAC,GAAG,CAAC,EAClB,SAAS,CACT,CAAC;IAEF,MAAM,MAAM,GAAG,IAAA,6BAAsB,EAIlC,QAAQ,CAAC,YAAY,CAAC,CAAC;IAE1B,MAAM,KAAK,GAAmB;QAC7B,OAAO,EAAE,CAAC;QACV,MAAM;QACN,QAAQ;QACR,QAAQ,EAAE;YACT,YAAY,EAAE,QAAQ,CAAC,YAAY;YACnC,aAAa,EAAE,QAAQ,CAAC,aAAa;YACrC,UAAU,EAAE,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,GAAG,QAAQ,CAAC,UAAU;YAC/D,QAAQ,EAAE,QAAQ,CAAC,QAAQ;YAC3B,KAAK,EAAE,QAAQ,CAAC,KAAK;SACrB;QACD,IAAI,EAAE,MAAM;YACX,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,CAAC,GAAG,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,IAAI,MAAM,CAAC,kBAAkB,EAAE;YACvE,CAAC,CAAC,SAAS;KACZ,CAAC;IACF,IAAA,wBAAe,EAAC,KAAK,CAAC,CAAC;IACvB,OAAO,KAAK,CAAC;AACd,CAAC"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.prompt = prompt;
|
|
4
|
+
const promises_1 = require("node:readline/promises");
|
|
5
|
+
/**
|
|
6
|
+
* Tiny prompt utility for interactive console input.
|
|
7
|
+
*
|
|
8
|
+
* The CLI uses this in two places:
|
|
9
|
+
* - `ritual init` (lazy-auth path): "Press Enter to open browser…"
|
|
10
|
+
* - any future command that needs to confirm a destructive action
|
|
11
|
+
*
|
|
12
|
+
* We deliberately avoid pulling in `inquirer` / `prompts` / etc. — Node's
|
|
13
|
+
* built-in `readline/promises` covers everything we need with zero dep
|
|
14
|
+
* surface. Keeps the install footprint small for a CLI that lives
|
|
15
|
+
* inside dev environments.
|
|
16
|
+
*/
|
|
17
|
+
/**
|
|
18
|
+
* Print `message` and wait for the user to press Enter. Returns the
|
|
19
|
+
* line they typed (if any) — usually empty for the "Press Enter" UX,
|
|
20
|
+
* but supported so callers can prompt for free-form input later.
|
|
21
|
+
*
|
|
22
|
+
* Throws on TTY-less stdin (CI / piped input). Caller must gate on
|
|
23
|
+
* `process.stdin.isTTY` before invoking — see init.ts for the pattern.
|
|
24
|
+
*/
|
|
25
|
+
async function prompt(message) {
|
|
26
|
+
const rl = (0, promises_1.createInterface)({ input: process.stdin, output: process.stdout });
|
|
27
|
+
try {
|
|
28
|
+
const answer = await rl.question(message);
|
|
29
|
+
return answer;
|
|
30
|
+
}
|
|
31
|
+
finally {
|
|
32
|
+
rl.close();
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
//# sourceMappingURL=prompt.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prompt.js","sourceRoot":"","sources":["../../src/lib/prompt.ts"],"names":[],"mappings":";;AAuBA,wBAQC;AA/BD,qDAAyD;AAEzD;;;;;;;;;;;GAWG;AAEH;;;;;;;GAOG;AACI,KAAK,UAAU,MAAM,CAAC,OAAe;IAC3C,MAAM,EAAE,GAAG,IAAA,0BAAe,EAAC,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;IAC7E,IAAI,CAAC;QACJ,MAAM,MAAM,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;QAC1C,OAAO,MAAM,CAAC;IACf,CAAC;YAAS,CAAC;QACV,EAAE,CAAC,KAAK,EAAE,CAAC;IACZ,CAAC;AACF,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ritualai/cli",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.2",
|
|
4
4
|
"description": "Ritual CLI — scaffold AI coding agent skills + register MCP servers. Connects Claude Code, Cursor, Windsurf, Kiro, Gemini CLI, VS Code/Copilot, and Codex to Ritual Cloud.",
|
|
5
5
|
"private": false,
|
|
6
6
|
"license": "Apache-2.0",
|