@ritualai/cli 0.7.2 → 0.7.5

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.
@@ -2,7 +2,13 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.loginCommand = loginCommand;
4
4
  const auth_flow_1 = require("../lib/auth-flow");
5
+ const config_1 = require("../lib/config");
6
+ const credentials_backup_1 = require("../lib/credentials-backup");
7
+ const identity_banner_1 = require("../lib/identity-banner");
8
+ const prompt_1 = require("../lib/prompt");
5
9
  const init_1 = require("./init");
10
+ const welcome_banner_1 = require("../lib/welcome-banner");
11
+ const package_info_1 = require("../lib/package-info");
6
12
  /**
7
13
  * `ritual login` — browser-based Auth Code + PKCE flow against
8
14
  * Keycloak. On success, stores the access + refresh tokens in
@@ -12,27 +18,128 @@ const init_1 = require("./init");
12
18
  * `--issuer https://auth.dev.ritualapp.cloud/realms/ritual` for dev,
13
19
  * `--dev` as the shortcut, or set `RITUAL_KEYCLOAK_URL` env var.
14
20
  *
21
+ * Three sign-in paths:
22
+ *
23
+ * 1. No valid local session: open browser, sign in normally.
24
+ * 2. Valid local session, no --switch-account: print identity
25
+ * banner to stderr, no-op (success), exit 0. The user already
26
+ * has what they need; we just confirm who they are.
27
+ * 3. Valid local session, --switch-account: atomic backup + forced
28
+ * sign-in (OIDC prompt=login so Keycloak's SSO cookie is
29
+ * ignored). On failure, prior session is restored.
30
+ *
15
31
  * The flow itself lives in `lib/auth-flow.ts` so `ritual init` can
16
32
  * invoke the same path when it lazily prompts the user to sign in.
17
33
  */
18
34
  async function loginCommand(options) {
19
- console.log('');
20
- console.log(' Ritual — sign in');
21
- console.log('');
22
35
  // --dev wins over --issuer (consistent with init); both win over env.
23
36
  const issuer = options.dev ? init_1.DEV_ISSUER : options.issuer;
37
+ // Welcome banner first — surfaces identity for the
38
+ // already-signed-in case BEFORE we decide whether to short-circuit.
39
+ const tokenStatus = await (0, config_1.getValidAccessToken)();
40
+ const projectDir = process.cwd();
41
+ const ws = (0, welcome_banner_1.readBoundWorkspace)(projectDir);
42
+ const currentUser = tokenStatus.kind === 'signed-in'
43
+ ? (tokenStatus.creds.user?.email ?? tokenStatus.creds.user?.sub)
44
+ : undefined;
45
+ (0, welcome_banner_1.printWelcomeBanner)({
46
+ currentUser,
47
+ workspaceBound: ws.bound,
48
+ workspaceName: ws.name,
49
+ projectDir,
50
+ cliVersion: (0, package_info_1.readPackageVersionSafe)(),
51
+ // `ritual login`'s "tips" are different from init's — focus on
52
+ // the auth surface specifically.
53
+ tips: tokenStatus.kind === 'signed-in'
54
+ ? undefined
55
+ : [
56
+ '1. Open your browser to Keycloak',
57
+ '2. Sign in (or verify email if brand-new)',
58
+ '3. Bounce back here; tokens cached locally',
59
+ ],
60
+ quickCommands: [
61
+ 'ritual whoami',
62
+ 'ritual login --switch-account',
63
+ 'ritual logout --all',
64
+ 'ritual doctor',
65
+ ],
66
+ });
67
+ // If a valid session exists and no --switch-account, also keep
68
+ // the existing compact identity banner for the textual "already
69
+ // signed in" message + exit.
70
+ if (tokenStatus.kind === 'signed-in' && !options.switchAccount) {
71
+ (0, identity_banner_1.printIdentityBanner)((0, identity_banner_1.identityFromCreds)(tokenStatus.creds), { indent: ' ' });
72
+ console.log('');
73
+ console.log(' Already signed in. Nothing to do.');
74
+ console.log('');
75
+ return;
76
+ }
77
+ const isSwitching = options.switchAccount && tokenStatus.kind === 'signed-in';
78
+ const currentEmail = tokenStatus.kind === 'signed-in'
79
+ ? (tokenStatus.creds.user?.email ?? tokenStatus.creds.user?.sub ?? '(unknown)')
80
+ : undefined;
81
+ if (isSwitching) {
82
+ console.log(` Currently signed in as ${currentEmail}.`);
83
+ console.log(` Continuing will:`);
84
+ console.log(` • Back up your local credentials, then atomically replace them on success`);
85
+ console.log(` • Open your browser with OIDC \`prompt=login\` (Keycloak will show its`);
86
+ console.log(` sign-in form even if its SSO cookie says otherwise — no incognito needed)`);
87
+ console.log(` If anything goes wrong, your existing session is restored.`);
88
+ console.log('');
89
+ if (!process.stdin.isTTY) {
90
+ if (!options.yes) {
91
+ console.error(` ✗ --switch-account requires interactive confirmation; pass --yes for scripted use.`);
92
+ console.error('');
93
+ process.exitCode = 1;
94
+ return;
95
+ }
96
+ }
97
+ else if (!options.yes) {
98
+ try {
99
+ await (0, prompt_1.prompt)(' Press Enter to switch, or Ctrl-C to keep the current session: ');
100
+ }
101
+ catch {
102
+ console.log('');
103
+ console.log(' Switch aborted.');
104
+ process.exitCode = 1;
105
+ return;
106
+ }
107
+ }
108
+ }
109
+ const loginRunner = async () => (0, auth_flow_1.runBrowserLoginAndSave)({
110
+ issuer,
111
+ clientId: options.clientId,
112
+ forceLogin: !!options.switchAccount,
113
+ });
24
114
  let creds;
25
- try {
26
- creds = await (0, auth_flow_1.runBrowserLoginAndSave)({
27
- issuer,
28
- clientId: options.clientId,
29
- });
115
+ if (isSwitching) {
116
+ const { release, backup } = (0, credentials_backup_1.beginCredentialSwap)();
117
+ (0, config_1.clearCredentials)();
118
+ try {
119
+ creds = await loginRunner();
120
+ backup.commit();
121
+ }
122
+ catch (err) {
123
+ backup.restore();
124
+ release();
125
+ console.error('');
126
+ console.error(` ✗ Switch failed: ${err.message}`);
127
+ console.error(` Restored previous session for ${currentEmail}.`);
128
+ process.exitCode = 1;
129
+ return;
130
+ }
131
+ release();
30
132
  }
31
- catch (err) {
32
- console.error('');
33
- console.error(` ✗ Login failed: ${err.message}`);
34
- process.exitCode = 1;
35
- return;
133
+ else {
134
+ try {
135
+ creds = await loginRunner();
136
+ }
137
+ catch (err) {
138
+ console.error('');
139
+ console.error(` ✗ Login failed: ${err.message}`);
140
+ process.exitCode = 1;
141
+ return;
142
+ }
36
143
  }
37
144
  const display = creds.user?.email ?? creds.user?.sub ?? 'unknown';
38
145
  console.log('');
@@ -1 +1 @@
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"}
1
+ {"version":3,"file":"login.js","sourceRoot":"","sources":["../../src/commands/login.ts"],"names":[],"mappings":";;AAgDA,oCA6HC;AA7KD,gDAA0D;AAC1D,0CAAsE;AACtE,kEAAgE;AAChE,4DAAgF;AAChF,0CAAuC;AACvC,iCAAoC;AACpC,0DAA+E;AAC/E,sDAA6D;AAmB7D;;;;;;;;;;;;;;;;;;;;;GAqBG;AACI,KAAK,UAAU,YAAY,CAAC,OAAqB;IACvD,sEAAsE;IACtE,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,iBAAU,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC;IAEzD,mDAAmD;IACnD,oEAAoE;IACpE,MAAM,WAAW,GAAG,MAAM,IAAA,4BAAmB,GAAE,CAAC;IAChD,MAAM,UAAU,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC;IACjC,MAAM,EAAE,GAAG,IAAA,mCAAkB,EAAC,UAAU,CAAC,CAAC;IAC1C,MAAM,WAAW,GAChB,WAAW,CAAC,IAAI,KAAK,WAAW;QAC/B,CAAC,CAAC,CAAC,WAAW,CAAC,KAAK,CAAC,IAAI,EAAE,KAAK,IAAI,WAAW,CAAC,KAAK,CAAC,IAAI,EAAE,GAAG,CAAC;QAChE,CAAC,CAAC,SAAS,CAAC;IACd,IAAA,mCAAkB,EAAC;QAClB,WAAW;QACX,cAAc,EAAE,EAAE,CAAC,KAAK;QACxB,aAAa,EAAE,EAAE,CAAC,IAAI;QACtB,UAAU;QACV,UAAU,EAAE,IAAA,qCAAsB,GAAE;QACpC,+DAA+D;QAC/D,iCAAiC;QACjC,IAAI,EAAE,WAAW,CAAC,IAAI,KAAK,WAAW;YACrC,CAAC,CAAC,SAAS;YACX,CAAC,CAAC;gBACD,kCAAkC;gBAClC,2CAA2C;gBAC3C,4CAA4C;aAC5C;QACF,aAAa,EAAE;YACd,eAAe;YACf,+BAA+B;YAC/B,qBAAqB;YACrB,eAAe;SACf;KACD,CAAC,CAAC;IAEH,+DAA+D;IAC/D,gEAAgE;IAChE,6BAA6B;IAC7B,IAAI,WAAW,CAAC,IAAI,KAAK,WAAW,IAAI,CAAC,OAAO,CAAC,aAAa,EAAE,CAAC;QAChE,IAAA,qCAAmB,EAAC,IAAA,mCAAiB,EAAC,WAAW,CAAC,KAAK,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;QAC5E,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAChB,OAAO,CAAC,GAAG,CAAC,qCAAqC,CAAC,CAAC;QACnD,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAChB,OAAO;IACR,CAAC;IAED,MAAM,WAAW,GAAG,OAAO,CAAC,aAAa,IAAI,WAAW,CAAC,IAAI,KAAK,WAAW,CAAC;IAC9E,MAAM,YAAY,GACjB,WAAW,CAAC,IAAI,KAAK,WAAW;QAC/B,CAAC,CAAC,CAAC,WAAW,CAAC,KAAK,CAAC,IAAI,EAAE,KAAK,IAAI,WAAW,CAAC,KAAK,CAAC,IAAI,EAAE,GAAG,IAAI,WAAW,CAAC;QAC/E,CAAC,CAAC,SAAS,CAAC;IAEd,IAAI,WAAW,EAAE,CAAC;QACjB,OAAO,CAAC,GAAG,CAAC,4BAA4B,YAAY,GAAG,CAAC,CAAC;QACzD,OAAO,CAAC,GAAG,CAAC,oBAAoB,CAAC,CAAC;QAClC,OAAO,CAAC,GAAG,CAAC,+EAA+E,CAAC,CAAC;QAC7F,OAAO,CAAC,GAAG,CAAC,4EAA4E,CAAC,CAAC;QAC1F,OAAO,CAAC,GAAG,CAAC,iFAAiF,CAAC,CAAC;QAC/F,OAAO,CAAC,GAAG,CAAC,8DAA8D,CAAC,CAAC;QAC5E,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAEhB,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC;YAC1B,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC;gBAClB,OAAO,CAAC,KAAK,CACZ,sFAAsF,CACtF,CAAC;gBACF,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;gBAClB,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;gBACrB,OAAO;YACR,CAAC;QACF,CAAC;aAAM,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC;YACzB,IAAI,CAAC;gBACJ,MAAM,IAAA,eAAM,EAAC,kEAAkE,CAAC,CAAC;YAClF,CAAC;YAAC,MAAM,CAAC;gBACR,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;gBAChB,OAAO,CAAC,GAAG,CAAC,mBAAmB,CAAC,CAAC;gBACjC,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;gBACrB,OAAO;YACR,CAAC;QACF,CAAC;IACF,CAAC;IAED,MAAM,WAAW,GAAG,KAAK,IAAI,EAAE,CAC9B,IAAA,kCAAsB,EAAC;QACtB,MAAM;QACN,QAAQ,EAAE,OAAO,CAAC,QAAQ;QAC1B,UAAU,EAAE,CAAC,CAAC,OAAO,CAAC,aAAa;KACnC,CAAC,CAAC;IAEJ,IAAI,KAAK,CAAC;IACV,IAAI,WAAW,EAAE,CAAC;QACjB,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,IAAA,wCAAmB,GAAE,CAAC;QAClD,IAAA,yBAAgB,GAAE,CAAC;QACnB,IAAI,CAAC;YACJ,KAAK,GAAG,MAAM,WAAW,EAAE,CAAC;YAC5B,MAAM,CAAC,MAAM,EAAE,CAAC;QACjB,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACd,MAAM,CAAC,OAAO,EAAE,CAAC;YACjB,OAAO,EAAE,CAAC;YACV,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;YAClB,OAAO,CAAC,KAAK,CAAC,sBAAuB,GAAa,CAAC,OAAO,EAAE,CAAC,CAAC;YAC9D,OAAO,CAAC,KAAK,CAAC,mCAAmC,YAAY,GAAG,CAAC,CAAC;YAClE,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;YACrB,OAAO;QACR,CAAC;QACD,OAAO,EAAE,CAAC;IACX,CAAC;SAAM,CAAC;QACP,IAAI,CAAC;YACJ,KAAK,GAAG,MAAM,WAAW,EAAE,CAAC;QAC7B,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACd,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;YAClB,OAAO,CAAC,KAAK,CAAC,qBAAsB,GAAa,CAAC,OAAO,EAAE,CAAC,CAAC;YAC7D,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;YACrB,OAAO;QACR,CAAC;IACF,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"}
@@ -1,25 +1,72 @@
1
1
  "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
2
5
  Object.defineProperty(exports, "__esModule", { value: true });
3
6
  exports.logoutCommand = logoutCommand;
7
+ const open_1 = __importDefault(require("open"));
4
8
  const config_1 = require("../lib/config");
9
+ const oidc_1 = require("../lib/oidc");
5
10
  /**
6
- * `ritual logout` — clears local credentials. Does NOT call Keycloak's
7
- * end-session endpoint that's a browser-side concept; clearing local
8
- * tokens is what matters from a CLI perspective. The user can sign out
9
- * of the realm session itself via the web app.
11
+ * `ritual logout` — clears local credentials. With `--all`, also
12
+ * opens the Keycloak browser logout endpoint to drop the IdP's SSO
13
+ * cookie (so the next sign-in won't silently auto-re-sign-you-in).
14
+ *
15
+ * Why no `--all` by default: the local-only case is the fast, common
16
+ * one. Most users want "this CLI forgets me"; few want the more
17
+ * heavyweight "this CLI forgets me AND my browser session ends."
10
18
  */
11
- async function logoutCommand() {
19
+ async function logoutCommand(options = {}) {
12
20
  const had = (0, config_1.loadCredentials)();
21
+ const display = had?.user?.email ?? had?.user?.sub ?? 'unknown';
13
22
  (0, config_1.clearCredentials)();
14
23
  console.log('');
15
24
  if (had) {
16
- const display = had.user?.email ?? had.user?.sub ?? 'unknown';
17
- console.log(` ✓ Signed out (${display}).`);
25
+ console.log(` ✓ Local credentials cleared (${display}).`);
18
26
  }
19
27
  else {
20
- console.log(' No active session — nothing to clear.');
28
+ console.log(' No active session — nothing to clear locally.');
21
29
  }
22
30
  console.log(` Credentials path: ${(0, config_1.getCredentialsPath)()}`);
31
+ if (options.all) {
32
+ if (!had) {
33
+ // Nothing to logout from on the IdP side either — no
34
+ // active session means no useful logout URL.
35
+ console.log('');
36
+ console.log(' No active browser SSO session to end (no local creds found).');
37
+ console.log('');
38
+ return;
39
+ }
40
+ // Build a logout URL with id_token_hint (recommended by OIDC
41
+ // RP-Initiated Logout 1.0 §2) and client_id. We intentionally
42
+ // do NOT set post_logout_redirect_uri — Keycloak requires
43
+ // pre-registration of those URIs on the client, and we don't
44
+ // want to couple this CLI feature to the realm-import path.
45
+ // Users land on Keycloak's default post-logout page, which
46
+ // reads "you have been logged out" — fine for our purposes.
47
+ const url = (0, oidc_1.buildLogoutUrl)({
48
+ issuer: had.issuer,
49
+ clientId: had.clientId,
50
+ idToken: had.tokenSet.id_token,
51
+ });
52
+ console.log('');
53
+ console.log(' Opening browser to end Keycloak SSO session…');
54
+ console.log(` If the browser doesn\'t open, visit:`);
55
+ console.log(` ${url}`);
56
+ try {
57
+ await (0, open_1.default)(url);
58
+ }
59
+ catch {
60
+ // Best-effort; the user can still paste the URL manually.
61
+ }
62
+ console.log('');
63
+ console.log(' ✓ Browser SSO logout requested.');
64
+ console.log('');
65
+ console.log(' Note: this does NOT revoke any of the following — manage them separately:');
66
+ console.log(' • Personal Access Tokens minted by `ritual init` (revoke via /settings/tokens)');
67
+ console.log(' • MCP server entries in your AI coding agents (edit each agent\'s mcp.json)');
68
+ console.log(' • Server-side refresh tokens (handled by Keycloak realm policy)');
69
+ }
23
70
  console.log('');
24
71
  }
25
72
  //# sourceMappingURL=logout.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"logout.js","sourceRoot":"","sources":["../../src/commands/logout.ts"],"names":[],"mappings":";;AAQA,sCAYC;AApBD,0CAAsF;AAEtF;;;;;GAKG;AACI,KAAK,UAAU,aAAa;IAClC,MAAM,GAAG,GAAG,IAAA,wBAAe,GAAE,CAAC;IAC9B,IAAA,yBAAgB,GAAE,CAAC;IACnB,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAChB,IAAI,GAAG,EAAE,CAAC;QACT,MAAM,OAAO,GAAG,GAAG,CAAC,IAAI,EAAE,KAAK,IAAI,GAAG,CAAC,IAAI,EAAE,GAAG,IAAI,SAAS,CAAC;QAC9D,OAAO,CAAC,GAAG,CAAC,mBAAmB,OAAO,IAAI,CAAC,CAAC;IAC7C,CAAC;SAAM,CAAC;QACP,OAAO,CAAC,GAAG,CAAC,yCAAyC,CAAC,CAAC;IACxD,CAAC;IACD,OAAO,CAAC,GAAG,CAAC,uBAAuB,IAAA,2BAAkB,GAAE,EAAE,CAAC,CAAC;IAC3D,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;AACjB,CAAC"}
1
+ {"version":3,"file":"logout.js","sourceRoot":"","sources":["../../src/commands/logout.ts"],"names":[],"mappings":";;;;;AA6BA,sCAwDC;AArFD,gDAAwB;AACxB,0CAAsF;AACtF,sCAA6C;AAkB7C;;;;;;;;GAQG;AACI,KAAK,UAAU,aAAa,CAAC,UAAyB,EAAE;IAC9D,MAAM,GAAG,GAAG,IAAA,wBAAe,GAAE,CAAC;IAC9B,MAAM,OAAO,GAAG,GAAG,EAAE,IAAI,EAAE,KAAK,IAAI,GAAG,EAAE,IAAI,EAAE,GAAG,IAAI,SAAS,CAAC;IAEhE,IAAA,yBAAgB,GAAE,CAAC;IAEnB,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAChB,IAAI,GAAG,EAAE,CAAC;QACT,OAAO,CAAC,GAAG,CAAC,kCAAkC,OAAO,IAAI,CAAC,CAAC;IAC5D,CAAC;SAAM,CAAC;QACP,OAAO,CAAC,GAAG,CAAC,iDAAiD,CAAC,CAAC;IAChE,CAAC;IACD,OAAO,CAAC,GAAG,CAAC,uBAAuB,IAAA,2BAAkB,GAAE,EAAE,CAAC,CAAC;IAE3D,IAAI,OAAO,CAAC,GAAG,EAAE,CAAC;QACjB,IAAI,CAAC,GAAG,EAAE,CAAC;YACV,qDAAqD;YACrD,6CAA6C;YAC7C,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;YAChB,OAAO,CAAC,GAAG,CAAC,gEAAgE,CAAC,CAAC;YAC9E,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;YAChB,OAAO;QACR,CAAC;QAED,6DAA6D;QAC7D,8DAA8D;QAC9D,0DAA0D;QAC1D,6DAA6D;QAC7D,4DAA4D;QAC5D,2DAA2D;QAC3D,4DAA4D;QAC5D,MAAM,GAAG,GAAG,IAAA,qBAAc,EAAC;YAC1B,MAAM,EAAE,GAAG,CAAC,MAAM;YAClB,QAAQ,EAAE,GAAG,CAAC,QAAQ;YACtB,OAAO,EAAE,GAAG,CAAC,QAAQ,CAAC,QAAQ;SAC9B,CAAC,CAAC;QAEH,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAChB,OAAO,CAAC,GAAG,CAAC,gDAAgD,CAAC,CAAC;QAC9D,OAAO,CAAC,GAAG,CAAC,wCAAwC,CAAC,CAAC;QACtD,OAAO,CAAC,GAAG,CAAC,OAAO,GAAG,EAAE,CAAC,CAAC;QAC1B,IAAI,CAAC;YACJ,MAAM,IAAA,cAAI,EAAC,GAAG,CAAC,CAAC;QACjB,CAAC;QAAC,MAAM,CAAC;YACR,0DAA0D;QAC3D,CAAC;QACD,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAChB,OAAO,CAAC,GAAG,CAAC,mCAAmC,CAAC,CAAC;QACjD,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAChB,OAAO,CAAC,GAAG,CAAC,6EAA6E,CAAC,CAAC;QAC3F,OAAO,CAAC,GAAG,CAAC,oFAAoF,CAAC,CAAC;QAClG,OAAO,CAAC,GAAG,CAAC,iFAAiF,CAAC,CAAC;QAC/F,OAAO,CAAC,GAAG,CAAC,qEAAqE,CAAC,CAAC;IACpF,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;AACjB,CAAC"}
package/dist/index.js CHANGED
@@ -9,12 +9,13 @@ const refresh_1 = require("./commands/refresh");
9
9
  const init_1 = require("./commands/init");
10
10
  const doctor_1 = require("./commands/doctor");
11
11
  const graph_1 = require("./commands/graph");
12
+ const package_info_1 = require("./lib/package-info");
12
13
  const program = new commander_1.Command();
13
14
  program
14
15
  .name('ritual')
15
16
  .description('Ritual CLI — connect AI coding agents to Ritual Cloud. ' +
16
17
  'Scaffold skills, register MCP servers, manage sessions.')
17
- .version('0.5.0');
18
+ .version((0, package_info_1.readPackageVersionSafe)());
18
19
  // `init` is the headline command: scaffold + register against every
19
20
  // detected agent. Listed first so `ritual --help` surfaces it.
20
21
  program
@@ -26,6 +27,8 @@ program
26
27
  .option('--client-id <id>', 'OIDC client id (defaults to "ritual-cli")')
27
28
  .option('--dev', '[internal] shortcut for --issuer https://auth.dev.ritualapp.cloud/realms/ritual')
28
29
  .option('--no-workspace', 'Skip the "create a workspace for this repo?" prompt. Useful for CI or when you want to bind a workspace by hand later.')
30
+ .option('--switch-account', 'Force a fresh sign-in even if you already have valid local credentials. Uses OIDC prompt=login so Keycloak ignores its SSO cookie. Atomic — your previous session is restored if anything fails.')
31
+ .option('--yes', 'Skip interactive confirmation prompts (required for --switch-account in non-TTY mode).')
29
32
  .action(init_1.initCommand);
30
33
  program
31
34
  .command('login')
@@ -33,10 +36,13 @@ program
33
36
  .option('--issuer <url>', 'OIDC issuer (defaults to https://auth.ritualapp.cloud/realms/ritual or RITUAL_KEYCLOAK_URL env)')
34
37
  .option('--client-id <id>', 'OIDC client id (defaults to "ritual-cli" or RITUAL_KEYCLOAK_CLIENT_ID env)')
35
38
  .option('--dev', '[internal] shortcut for --issuer https://auth.dev.ritualapp.cloud/realms/ritual')
39
+ .option('--switch-account', 'Force a fresh sign-in even if you already have valid local credentials. Uses OIDC prompt=login so Keycloak ignores its SSO cookie.')
40
+ .option('--yes', 'Skip interactive confirmation prompts (required for --switch-account in non-TTY mode).')
36
41
  .action(login_1.loginCommand);
37
42
  program
38
43
  .command('logout')
39
- .description('Clear local credentials')
44
+ .description('Clear local credentials. With --all, also end the Keycloak browser SSO session.')
45
+ .option('--all', 'Also open the browser to end your Keycloak SSO session (so the next sign-in shows the form instead of auto-re-using your previous account).')
40
46
  .action(logout_1.logoutCommand);
41
47
  program
42
48
  .command('whoami')
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;AAClD,4CAAsD;AAEtD,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,CACN,gBAAgB,EAChB,wHAAwH,CACxH;KACA,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,iEAAiE;AACjE,+DAA+D;AAC/D,kDAAkD;AAClD,MAAM,KAAK,GAAG,OAAO;KACnB,OAAO,CAAC,OAAO,CAAC;KAChB,WAAW,CAAC,oEAAoE,CAAC,CAAC;AAEpF,KAAK;KACH,OAAO,CAAC,QAAQ,CAAC;KACjB,WAAW,CAAC,mEAAmE,CAAC;KAChF,MAAM,CACN,kBAAkB,EAClB,0FAA0F,CAC1F;KACA,MAAM,CAAC,aAAa,EAAE,8DAA8D,CAAC;KACrF,MAAM,CAAC,0BAAkB,CAAC,CAAC;AAE7B,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;AAClD,4CAAsD;AACtD,qDAA4D;AAE5D,MAAM,OAAO,GAAG,IAAI,mBAAO,EAAE,CAAC;AAE9B,OAAO;KACL,IAAI,CAAC,QAAQ,CAAC;KACd,WAAW,CACX,yDAAyD;IACxD,yDAAyD,CAC1D;KACA,OAAO,CAAC,IAAA,qCAAsB,GAAE,CAAC,CAAC;AAEpC,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,CACN,gBAAgB,EAChB,wHAAwH,CACxH;KACA,MAAM,CACN,kBAAkB,EAClB,kMAAkM,CAClM;KACA,MAAM,CACN,OAAO,EACP,wFAAwF,CACxF;KACA,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,CACN,kBAAkB,EAClB,oIAAoI,CACpI;KACA,MAAM,CACN,OAAO,EACP,wFAAwF,CACxF;KACA,MAAM,CAAC,oBAAY,CAAC,CAAC;AAEvB,OAAO;KACL,OAAO,CAAC,QAAQ,CAAC;KACjB,WAAW,CAAC,iFAAiF,CAAC;KAC9F,MAAM,CACN,OAAO,EACP,6IAA6I,CAC7I;KACA,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,iEAAiE;AACjE,+DAA+D;AAC/D,kDAAkD;AAClD,MAAM,KAAK,GAAG,OAAO;KACnB,OAAO,CAAC,OAAO,CAAC;KAChB,WAAW,CAAC,oEAAoE,CAAC,CAAC;AAEpF,KAAK;KACH,OAAO,CAAC,QAAQ,CAAC;KACjB,WAAW,CAAC,mEAAmE,CAAC;KAChF,MAAM,CACN,kBAAkB,EAClB,0FAA0F,CAC1F;KACA,MAAM,CAAC,aAAa,EAAE,8DAA8D,CAAC;KACrF,MAAM,CAAC,0BAAkB,CAAC,CAAC;AAE7B,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"}
@@ -49,7 +49,14 @@ exports.PROVIDERS = [
49
49
  {
50
50
  name: 'Cursor',
51
51
  id: 'cursor',
52
- detect: () => (0, node_fs_1.existsSync)((0, node_path_1.join)((0, node_os_1.homedir)(), '.cursor')),
52
+ // Tightened 2026-05-13: `~/.cursor` exists as soon as a user
53
+ // downloads Cursor; that's not strong enough evidence the IDE
54
+ // is actually in use. Require either an extensions dir, the
55
+ // settings file, or an existing MCP config — all of which only
56
+ // appear after Cursor has been launched at least once.
57
+ detect: () => (0, node_fs_1.existsSync)((0, node_path_1.join)((0, node_os_1.homedir)(), '.cursor', 'extensions')) ||
58
+ (0, node_fs_1.existsSync)((0, node_path_1.join)((0, node_os_1.homedir)(), '.cursor', 'settings.json')) ||
59
+ (0, node_fs_1.existsSync)((0, node_path_1.join)((0, node_os_1.homedir)(), '.cursor', 'mcp.json')),
53
60
  projectSkillDir: '.cursor/rules',
54
61
  packageSkillDir: 'skills/cursor',
55
62
  mcpConfigMethod: 'json-file',
@@ -58,8 +65,12 @@ exports.PROVIDERS = [
58
65
  {
59
66
  name: 'Windsurf',
60
67
  id: 'windsurf',
61
- // Windsurf is Codeium's IDE; the dotdir is `.codeium`.
62
- detect: () => (0, node_fs_1.existsSync)((0, node_path_1.join)((0, node_os_1.homedir)(), '.codeium')),
68
+ // Tightened 2026-05-13: `~/.codeium` is created by the Codeium
69
+ // VS Code/JetBrains extension too most dev machines that have
70
+ // ever installed Codeium autocomplete have it, even if they
71
+ // never installed Windsurf the IDE. The `windsurf` subdir is
72
+ // specifically created by Windsurf itself.
73
+ detect: () => (0, node_fs_1.existsSync)((0, node_path_1.join)((0, node_os_1.homedir)(), '.codeium', 'windsurf')),
63
74
  projectSkillDir: '.windsurf/rules',
64
75
  // Windsurf accepts the same rules format Cursor does, so we ship
65
76
  // the same bundle.
@@ -1 +1 @@
1
- {"version":3,"file":"providers.js","sourceRoot":"","sources":["../../../src/lib/agents/providers.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"providers.js","sourceRoot":"","sources":["../../../src/lib/agents/providers.ts"],"names":[],"mappings":"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"}
@@ -39,7 +39,7 @@ async function runBrowserLoginAndSave(opts = {}) {
39
39
  const issuer = opts.issuer ?? exports.DEFAULT_ISSUER;
40
40
  const clientId = opts.clientId ?? exports.DEFAULT_CLIENT_ID;
41
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);
42
+ const tokenSet = await (0, oidc_1.performLoginFlow)({ issuer, clientId, scope: exports.DEFAULT_SCOPE, forceLogin: opts.forceLogin }, (url) => (0, open_1.default)(url), onMessage);
43
43
  const claims = (0, oidc_1.decodeJwtPayloadUnsafe)(tokenSet.access_token);
44
44
  const creds = {
45
45
  version: 1,
@@ -1 +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"}
1
+ {"version":3,"file":"auth-flow.js","sourceRoot":"","sources":["../../src/lib/auth-flow.ts"],"names":[],"mappings":";;;;;;AAqDA,wDAoCC;AAzFD,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;AAqB7E;;;;;;;;;;;;;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,UAAU,EAAE,IAAI,CAAC,UAAU,EAAE,EACvE,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,182 @@
1
+ "use strict";
2
+ /**
3
+ * Tiny ANSI color helper. Zero dependencies — we hand-roll the
4
+ * escape codes so the CLI install footprint stays minimal.
5
+ *
6
+ * Capabilities:
7
+ *
8
+ * - **Truecolor (24-bit)** when the terminal advertises it
9
+ * (`COLORTERM=truecolor|24bit`) — used to render Ritual's exact
10
+ * brand teal `#1FAF9F` faithfully.
11
+ * - **256-color (8-bit) fallback** for terminals that only
12
+ * advertise 256 colors — quantized to the nearest 256-color slot
13
+ * so brand identity survives.
14
+ * - **No color at all** when the user has set `NO_COLOR` (see
15
+ * <https://no-color.org/>), is piping output to a non-TTY, or is
16
+ * on a terminal that doesn't claim color support.
17
+ *
18
+ * Detection precedence (highest to lowest):
19
+ *
20
+ * 1. `process.env.NO_COLOR` set → strip all color
21
+ * 2. Not a TTY (`!process.stdout.isTTY`) → strip all color
22
+ * 3. `process.env.FORCE_COLOR=1|2|3` → force on (debug, screenshots)
23
+ * 4. `process.env.COLORTERM=truecolor|24bit` → 24-bit
24
+ * 5. `process.env.TERM` includes `256color` → 8-bit
25
+ * 6. Anything else → 4-bit (16 colors) basic ANSI
26
+ */
27
+ Object.defineProperty(exports, "__esModule", { value: true });
28
+ exports.RITUAL_TEAL = exports.DIM = exports.BOLD = exports.RESET = void 0;
29
+ exports.detectColorMode = detectColorMode;
30
+ exports.fg = fg;
31
+ exports.color = color;
32
+ exports.boldColor = boldColor;
33
+ exports.dim = dim;
34
+ /**
35
+ * Detect the highest color tier we can use on this terminal. Cached
36
+ * after first call since env vars don't change mid-process for
37
+ * practical terminal sessions. Re-exported as a function (not a
38
+ * constant) so tests can `jest.resetModules()` and re-detect.
39
+ */
40
+ function detectColorMode() {
41
+ if (process.env.NO_COLOR !== undefined)
42
+ return 'none';
43
+ if (!process.stdout.isTTY && process.env.FORCE_COLOR === undefined)
44
+ return 'none';
45
+ if (process.env.FORCE_COLOR === '3')
46
+ return 'truecolor';
47
+ const colorterm = (process.env.COLORTERM ?? '').toLowerCase();
48
+ if (colorterm === 'truecolor' || colorterm === '24bit')
49
+ return 'truecolor';
50
+ const term = (process.env.TERM ?? '').toLowerCase();
51
+ if (term.includes('256color'))
52
+ return 'ansi256';
53
+ if (term && term !== 'dumb')
54
+ return 'ansi16';
55
+ return process.env.FORCE_COLOR !== undefined ? 'ansi16' : 'none';
56
+ }
57
+ /** Reset all formatting. */
58
+ exports.RESET = '\x1b[0m';
59
+ /** Bold. */
60
+ exports.BOLD = '\x1b[1m';
61
+ /** Dim. Used for secondary text in the welcome box. */
62
+ exports.DIM = '\x1b[2m';
63
+ /**
64
+ * Build a foreground-color escape sequence for the given RGB triple,
65
+ * downgraded according to the terminal's color tier.
66
+ *
67
+ * - `truecolor` → `\x1b[38;2;R;G;Bm`
68
+ * - `ansi256` → `\x1b[38;5;Nm` (quantized to nearest 256-color slot)
69
+ * - `ansi16` → `\x1b[36m` (nearest base color — for teal/cyan we
70
+ * pick cyan; same for any cool color)
71
+ * - `none` → empty string
72
+ */
73
+ function fg(rgb, mode = detectColorMode()) {
74
+ if (mode === 'none')
75
+ return '';
76
+ if (mode === 'truecolor') {
77
+ return `\x1b[38;2;${rgb[0]};${rgb[1]};${rgb[2]}m`;
78
+ }
79
+ if (mode === 'ansi256') {
80
+ return `\x1b[38;5;${rgbToAnsi256(rgb)}m`;
81
+ }
82
+ // ansi16: pick the closest of the 16 base colors. We classify by
83
+ // hue rather than by Euclidean distance — for brand teal that
84
+ // means "cyan-ish" not "green-ish."
85
+ return `\x1b[${rgbToBase16Fg(rgb)}m`;
86
+ }
87
+ /**
88
+ * Convenience: Ritual brand teal. Pulled from the canonical SVG icon
89
+ * at `apps/cli/assets/...` (`fill="#1FAF9F"`). One place to change
90
+ * if the brand ever shifts.
91
+ */
92
+ exports.RITUAL_TEAL = [0x1f, 0xaf, 0x9f]; // #1FAF9F
93
+ /**
94
+ * Convenience helper to wrap text in foreground color + reset.
95
+ *
96
+ * color(RITUAL_TEAL, 'Hello') → '\x1b[38;2;31;175;159mHello\x1b[0m'
97
+ *
98
+ * Safe when color mode is `none` — returns the text untouched (no
99
+ * empty escape sequences in the output).
100
+ */
101
+ function color(rgb, text) {
102
+ const mode = detectColorMode();
103
+ if (mode === 'none')
104
+ return text;
105
+ return `${fg(rgb, mode)}${text}${exports.RESET}`;
106
+ }
107
+ /**
108
+ * Bold-and-colored variant. Used for the brand wordmark in the
109
+ * welcome box header.
110
+ */
111
+ function boldColor(rgb, text) {
112
+ const mode = detectColorMode();
113
+ if (mode === 'none')
114
+ return text;
115
+ return `${exports.BOLD}${fg(rgb, mode)}${text}${exports.RESET}`;
116
+ }
117
+ /** Wrap text in dim. Used for secondary info inside the welcome box. */
118
+ function dim(text) {
119
+ const mode = detectColorMode();
120
+ if (mode === 'none')
121
+ return text;
122
+ return `${exports.DIM}${text}${exports.RESET}`;
123
+ }
124
+ // ─── internal: color-space conversions ──────────────────────────────────────
125
+ /**
126
+ * Map an RGB triple to its nearest 256-color (xterm 256) slot.
127
+ *
128
+ * The 256-color palette is structured as:
129
+ * - 0–15: the 16 base ANSI colors (varies by terminal theme)
130
+ * - 16–231: a 6×6×6 RGB cube (each channel ∈ {0,95,135,175,215,255})
131
+ * - 232–255: a 24-step grayscale ramp
132
+ *
133
+ * For brand fidelity we map into the 6×6×6 cube — the base 16 are
134
+ * user-themeable and unreliable for "exact" colors.
135
+ */
136
+ function rgbToAnsi256(rgb) {
137
+ const cubeAxis = (c) => {
138
+ // 6×6×6 cube quantization: 0, 95, 135, 175, 215, 255.
139
+ if (c < 48)
140
+ return 0;
141
+ if (c < 115)
142
+ return 1;
143
+ return Math.floor((c - 35) / 40);
144
+ };
145
+ const r = cubeAxis(rgb[0]);
146
+ const g = cubeAxis(rgb[1]);
147
+ const b = cubeAxis(rgb[2]);
148
+ return 16 + 36 * r + 6 * g + b;
149
+ }
150
+ /**
151
+ * Map an RGB triple to the nearest of the 8 standard ANSI foreground
152
+ * codes (30–37). We extend to bright variants (90–97) when the input
153
+ * is bright enough — `#1FAF9F` is mid-saturation cyan so it lands on
154
+ * 36 (cyan) cleanly.
155
+ */
156
+ function rgbToBase16Fg(rgb) {
157
+ const [r, g, b] = rgb;
158
+ const max = Math.max(r, g, b);
159
+ const min = Math.min(r, g, b);
160
+ const bright = max > 170;
161
+ // Grayscale-ish (low saturation): default to white if bright, else neutral.
162
+ if (max - min < 30) {
163
+ return bright ? 97 : 37;
164
+ }
165
+ // Color classification by dominant channel(s):
166
+ // - High green + high blue → cyan
167
+ // - High red + high blue → magenta
168
+ // - High red + high green → yellow
169
+ // - High red → red, high green → green, high blue → blue
170
+ if (g > 80 && b > 80 && g + b > r * 1.5)
171
+ return bright ? 96 : 36; // cyan
172
+ if (r > 80 && b > 80 && r + b > g * 1.5)
173
+ return bright ? 95 : 35; // magenta
174
+ if (r > 80 && g > 80 && r + g > b * 1.5)
175
+ return bright ? 93 : 33; // yellow
176
+ if (r >= g && r >= b)
177
+ return bright ? 91 : 31; // red
178
+ if (g >= r && g >= b)
179
+ return bright ? 92 : 32; // green
180
+ return bright ? 94 : 34; // blue
181
+ }
182
+ //# sourceMappingURL=colors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"colors.js","sourceRoot":"","sources":["../../src/lib/colors.ts"],"names":[],"mappings":"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"}