@ritualai/cli 0.3.2 → 0.4.0

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 CHANGED
@@ -30,7 +30,7 @@ Hit Enter, complete the browser OAuth flow, and `init` resumes
30
30
  automatically. Subsequent `init` runs skip the prompt (credentials are
31
31
  cached and refreshed automatically).
32
32
 
33
- `init` does four things:
33
+ `init` does five things:
34
34
 
35
35
  1. **Signs you in** if you aren't already (browser OAuth, npm-style
36
36
  "press Enter to open browser" prompt). Skipped if already signed in.
@@ -39,7 +39,13 @@ cached and refreshed automatically).
39
39
  3. **Mints a long-lived Personal Access Token** via the Ritual API
40
40
  named `Ritual CLI — <hostname>`, so the agent has a credential
41
41
  that doesn't expire every 5 minutes the way OAuth tokens do.
42
- 4. **For each detected agent:** copies the Ritual skill files into your
42
+ 4. **Binds a project workspace.** If `.ritual/config.json` doesn't
43
+ exist, suggests creating one named after your repo (`git remote
44
+ get-url origin` → fall back to cwd basename). Y/n/custom-name
45
+ prompt. Writes the binding to `.ritual/config.json` so future tool
46
+ calls default to this workspace. Commit that file — your team uses
47
+ the same workspace. Pass `--no-workspace` to skip.
48
+ 5. **For each detected agent:** copies the Ritual skill files into your
43
49
  project (`.claude/skills/`, `.cursor/rules/`, etc.) AND writes
44
50
  the MCP server config (`claude mcp add-json` for Claude Code, or
45
51
  `mcp.json` merge for the others) with the PAT as the Bearer.
@@ -11,6 +11,7 @@ const configure_mcp_1 = require("../lib/agents/configure-mcp");
11
11
  const skill_copy_1 = require("../lib/skill-copy");
12
12
  const auth_flow_1 = require("../lib/auth-flow");
13
13
  const prompt_1 = require("../lib/prompt");
14
+ const workspace_flow_1 = require("../lib/workspace-flow");
14
15
  /**
15
16
  * Issuer URL for the dev shortcut. Exported so `ritual login --dev`
16
17
  * can use the same constant (single source of truth — if we ever flip
@@ -174,8 +175,25 @@ async function initCommand(opts = {}) {
174
175
  console.log(` ✓ Minted ${pat.name}`);
175
176
  console.log(` Manage tokens at: ${webAppUrlFromIssuer(issuer)}/settings/tokens`);
176
177
  console.log('');
177
- // --- 4. Copy skills + register MCP for each target agent ---------
178
+ // --- 3.5 Bind a project workspace --------------------------------
179
+ // Project-scoped state — see ./../lib/workspace-flow.ts for the
180
+ // resolution rules. The result is null when:
181
+ // - .ritual/config.json already exists (no change to make)
182
+ // - non-TTY mode (CI)
183
+ // - --no-workspace flag passed
184
+ // - user explicitly said "n" at the prompt
185
+ // - workspace creation failed (warning printed by the helper)
186
+ // We don't fail init when this returns null — the project just
187
+ // doesn't get a default workspace bound, and downstream tools will
188
+ // prompt for one on first use.
178
189
  const projectDir = opts.cwd ?? process.cwd();
190
+ // Commander semantics: `--no-workspace` sets `opts.workspace=false`.
191
+ // Default (no flag) leaves it `undefined`. Treat anything except
192
+ // explicit false as "go ahead and prompt".
193
+ if (opts.workspace !== false) {
194
+ await (0, workspace_flow_1.resolveProjectWorkspace)({ api, projectDir });
195
+ }
196
+ // --- 4. Copy skills + register MCP for each target agent ---------
179
197
  const copyResults = [];
180
198
  const registrationResults = [];
181
199
  for (const t of targets) {
@@ -1 +1 @@
1
- {"version":3,"file":"init.js","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"init.js","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":";;;AAiGA,kCAqMC;AAtSD,0CAAoD;AACpD,kDAAgE;AAChE,gDAAgD;AAChD,qDAGgC;AAChC,uDAAsE;AACtE,+DAGqC;AACrC,kDAA2E;AAC3E,gDAA0D;AAC1D,0CAAuC;AACvC,0DAAgE;AA0DhE;;;;GAIG;AACU,QAAA,UAAU,GAAG,gDAAgD,CAAC;AAE3E;;;;;;;;;;GAUG;AACH,SAAS,oBAAoB,CAAC,IAAiB;IAC9C,IAAI,IAAI,CAAC,GAAG;QAAE,OAAO,kBAAU,CAAC;IAChC,IAAI,IAAI,CAAC,MAAM;QAAE,OAAO,IAAI,CAAC,MAAM,CAAC;IACpC,OAAO,SAAS,CAAC,CAAC,2CAA2C;AAC9D,CAAC;AAEM,KAAK,UAAU,WAAW,CAAC,OAAoB,EAAE;IACvD,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAChB,OAAO,CAAC,GAAG,CAAC,6DAA6D,CAAC,CAAC;IAC3E,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAEhB,mEAAmE;IACnE,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;QACf,OAAO,CAAC,GAAG,CAAC,iBAAiB,CAAC,CAAC;QAC/B,KAAK,MAAM,CAAC,IAAI,qBAAS,EAAE,CAAC;YAC3B,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;QACjD,CAAC;QACD,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAChB,OAAO;IACR,CAAC;IAED,0EAA0E;IAC1E,EAAE;IACF,2CAA2C;IAC3C,mEAAmE;IACnE,iEAAiE;IACjE,iEAAiE;IACjE,+DAA+D;IAC/D,oCAAoC;IACpC,IAAI,WAAW,GAAG,MAAM,IAAA,4BAAmB,GAAE,CAAC;IAE9C,IAAI,WAAW,CAAC,IAAI,KAAK,WAAW,EAAE,CAAC;QACtC,MAAM,MAAM,GACX,WAAW,CAAC,IAAI,KAAK,kBAAkB;YACtC,CAAC,CAAC,oBAAoB,WAAW,CAAC,MAAM,GAAG;YAC3C,CAAC,CAAC,uBAAuB,CAAC;QAE5B,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC;YAC1B,OAAO,CAAC,KAAK,CAAC,OAAO,MAAM,qDAAqD,CAAC,CAAC;YAClF,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;YAClB,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;YACrB,OAAO;QACR,CAAC;QAED,OAAO,CAAC,GAAG,CAAC,KAAK,UAAU,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QACxC,IAAI,CAAC;YACJ,MAAM,IAAA,eAAM,EAAC,gEAAgE,CAAC,CAAC;QAChF,CAAC;QAAC,MAAM,CAAC;YACR,qDAAqD;YACrD,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;YAChB,OAAO,CAAC,GAAG,CAAC,oBAAoB,CAAC,CAAC;YAClC,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;YACrB,OAAO;QACR,CAAC;QAED,IAAI,CAAC;YACJ,MAAM,IAAA,kCAAsB,EAAC;gBAC5B,MAAM,EAAE,oBAAoB,CAAC,IAAI,CAAC;gBAClC,QAAQ,EAAE,IAAI,CAAC,QAAQ;aACvB,CAAC,CAAC;QACJ,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACd,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;YAClB,OAAO,CAAC,KAAK,CAAC,iCAAkC,GAAa,CAAC,OAAO,EAAE,CAAC,CAAC;YACzE,OAAO,CAAC,KAAK,CAAC,2DAA2D,CAAC,CAAC;YAC3E,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;YAClB,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;YACrB,OAAO;QACR,CAAC;QAED,+DAA+D;QAC/D,qDAAqD;QACrD,WAAW,GAAG,MAAM,IAAA,4BAAmB,GAAE,CAAC;QAC1C,IAAI,WAAW,CAAC,IAAI,KAAK,WAAW,EAAE,CAAC;YACtC,+DAA+D;YAC/D,OAAO,CAAC,KAAK,CAAC,wEAAwE,CAAC,CAAC;YACxF,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;YACrB,OAAO;QACR,CAAC;QACD,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAChB,OAAO,CAAC,GAAG,CAAC,oBAAoB,WAAW,CAAC,KAAK,CAAC,IAAI,EAAE,KAAK,IAAI,WAAW,CAAC,KAAK,CAAC,IAAI,EAAE,GAAG,IAAI,SAAS,EAAE,CAAC,CAAC;QAC7G,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IACjB,CAAC;IAED,oEAAoE;IACpE,IAAI,OAA0B,CAAC;IAE/B,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;QAChB,MAAM,QAAQ,GAAG,IAAA,4BAAgB,EAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAC9C,IAAI,CAAC,QAAQ,EAAE,CAAC;YACf,OAAO,CAAC,KAAK,CAAC,sBAAsB,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC;YAClD,OAAO,CAAC,KAAK,CAAC,mDAAmD,CAAC,CAAC;YACnE,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;YAClB,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;YACrB,OAAO;QACR,CAAC;QACD,+DAA+D;QAC/D,6DAA6D;QAC7D,qBAAqB;QACrB,OAAO,GAAG;YACT;gBACC,EAAE,EAAE,QAAQ,CAAC,EAAE;gBACf,IAAI,EAAE,QAAQ,CAAC,IAAI;gBACnB,QAAQ,EAAE,IAAI;gBACd,QAAQ;aACR;SACD,CAAC;IACH,CAAC;SAAM,CAAC;QACP,MAAM,GAAG,GAAG,IAAA,uBAAY,GAAE,CAAC;QAC3B,MAAM,QAAQ,GAAG,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC;QAC/C,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC3B,0DAA0D;YAC1D,wDAAwD;YACxD,kDAAkD;YAClD,MAAM,cAAc,GAAG,IAAA,4BAAgB,EAAC,aAAa,CAAE,CAAC;YACxD,OAAO,GAAG;gBACT;oBACC,EAAE,EAAE,cAAc,CAAC,EAAE;oBACrB,IAAI,EAAE,cAAc,CAAC,IAAI;oBACzB,QAAQ,EAAE,KAAK;oBACf,QAAQ,EAAE,cAAc;iBACxB;aACD,CAAC;YACF,OAAO,CAAC,GAAG,CAAC,8CAA8C,CAAC,CAAC;YAC5D,OAAO,CAAC,GAAG,CAAC,mBAAmB,cAAc,CAAC,IAAI,0CAA0C,CAAC,CAAC;YAC9F,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QACjB,CAAC;aAAM,CAAC;YACP,OAAO,GAAG,QAAQ,CAAC;YACnB,OAAO,CAAC,GAAG,CAAC,cAAc,QAAQ,CAAC,MAAM,cAAc,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YACjG,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QACjB,CAAC;IACF,CAAC;IAED,oEAAoE;IACpE,MAAM,MAAM,GAAG,WAAW,CAAC,KAAK,CAAC,MAAM,CAAC;IACxC,MAAM,GAAG,GAAG,IAAI,sBAAS,CAAC;QACzB,MAAM;QACN,WAAW,EAAE,WAAW,CAAC,WAAW;KACpC,CAAC,CAAC;IACH,MAAM,MAAM,GAAG,IAAA,6BAAgB,EAAC,MAAM,CAAC,CAAC;IAExC,IAAI,GAA6C,CAAC;IAClD,IAAI,CAAC;QACJ,GAAG,GAAG,MAAM,IAAA,wBAAY,EAAC,EAAE,GAAG,EAAE,CAAC,CAAC;IACnC,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACd,OAAO,CAAC,KAAK,CAAC,oCAAqC,GAAa,CAAC,OAAO,EAAE,CAAC,CAAC;QAC5E,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;QAClB,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;QACrB,OAAO;IACR,CAAC;IACD,OAAO,CAAC,GAAG,CAAC,cAAc,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC;IACtC,OAAO,CAAC,GAAG,CAAC,yBAAyB,mBAAmB,CAAC,MAAM,CAAC,kBAAkB,CAAC,CAAC;IACpF,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAEhB,oEAAoE;IACpE,gEAAgE;IAChE,6CAA6C;IAC7C,6DAA6D;IAC7D,wBAAwB;IACxB,iCAAiC;IACjC,6CAA6C;IAC7C,gEAAgE;IAChE,+DAA+D;IAC/D,mEAAmE;IACnE,+BAA+B;IAC/B,MAAM,UAAU,GAAG,IAAI,CAAC,GAAG,IAAI,OAAO,CAAC,GAAG,EAAE,CAAC;IAC7C,qEAAqE;IACrE,iEAAiE;IACjE,2CAA2C;IAC3C,IAAI,IAAI,CAAC,SAAS,KAAK,KAAK,EAAE,CAAC;QAC9B,MAAM,IAAA,wCAAuB,EAAC,EAAE,GAAG,EAAE,UAAU,EAAE,CAAC,CAAC;IACpD,CAAC;IAED,oEAAoE;IACpE,MAAM,WAAW,GAAiB,EAAE,CAAC;IACrC,MAAM,mBAAmB,GAAyB,EAAE,CAAC;IAErD,KAAK,MAAM,CAAC,IAAI,OAAO,EAAE,CAAC;QACzB,WAAW,CAAC,IAAI,CAAC,IAAA,kCAAqB,EAAC,CAAC,CAAC,QAAQ,EAAE,UAAU,CAAC,CAAC,CAAC;QAChE,mBAAmB,CAAC,IAAI,CACvB,IAAA,oCAAoB,EAAC,CAAC,CAAC,QAAQ,EAAE,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,CAAC,cAAc,EAAE,CAAC,CAC5E,CAAC;IACH,CAAC;IAED,oEAAoE;IACpE,OAAO,CAAC,GAAG,CAAC,sBAAsB,CAAC,CAAC;IACpC,KAAK,MAAM,CAAC,IAAI,OAAO,EAAE,CAAC;QACzB,MAAM,IAAI,GAAG,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,KAAK,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAE,CAAC;QACvE,MAAM,GAAG,GAAG,mBAAmB,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,KAAK,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAE,CAAC;QAC9E,MAAM,YAAY,GACjB,IAAI,CAAC,MAAM,GAAG,CAAC;YACd,CAAC,CAAC,GAAG,IAAI,CAAC,MAAM,eAAe,CAAC,CAAC,QAAQ,CAAC,eAAe,GAAG;YAC5D,CAAC,CAAC,mBAAmB,IAAI,CAAC,MAAM,IAAI,SAAS,GAAG,CAAC;QACnD,MAAM,UAAU,GAAG,GAAG,CAAC,OAAO;YAC7B,CAAC,CAAC,uBAAuB;YACzB,CAAC,CAAC,wBAAwB,GAAG,CAAC,MAAM,IAAI,SAAS,EAAE,CAAC;QACrD,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAC;QACtC,OAAO,CAAC,GAAG,CAAC,SAAS,YAAY,EAAE,CAAC,CAAC;QACrC,OAAO,CAAC,GAAG,CAAC,SAAS,UAAU,EAAE,CAAC,CAAC;IACpC,CAAC;IACD,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAChB,OAAO,CAAC,GAAG,CAAC,yEAAyE,CAAC,CAAC;IACvF,OAAO,CAAC,GAAG,CAAC,sDAAsD,CAAC,CAAC;IACpE,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;AACjB,CAAC;AAED,sFAAsF;AACtF,SAAS,UAAU,CAAC,CAAS;IAC5B,OAAO,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AAC7D,CAAC;AAED;;;;;;GAMG;AACH,SAAS,mBAAmB,CAAC,MAAc;IAC1C,IAAI,CAAC;QACJ,MAAM,CAAC,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,CAAC;QAC1B,MAAM,IAAI,GAAG,CAAC,CAAC,IAAI,CAAC;QACpB,IAAI,IAAI,CAAC,UAAU,CAAC,WAAW,CAAC;YAAE,OAAO,6BAA6B,CAAC;QACvE,IAAI,IAAI,KAAK,sBAAsB;YAAE,OAAO,6BAA6B,CAAC;QAC1E,qDAAqD;QACrD,OAAO,WAAW,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,MAAM,CAAC,EAAE,CAAC;IACrD,CAAC;IAAC,MAAM,CAAC;QACR,OAAO,6BAA6B,CAAC;IACtC,CAAC;AACF,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.2');
16
+ .version('0.4.0');
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
@@ -24,6 +24,7 @@ program
24
24
  .option('--issuer <url>', 'OIDC issuer for the lazy-auth flow (defaults to prod or RITUAL_KEYCLOAK_URL env)')
25
25
  .option('--client-id <id>', 'OIDC client id (defaults to "ritual-cli")')
26
26
  .option('--dev', '[internal] shortcut for --issuer https://auth.dev.ritualapp.cloud/realms/ritual')
27
+ .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.')
27
28
  .action(init_1.initCommand);
28
29
  program
29
30
  .command('login')
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,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"}
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,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,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"}
@@ -26,9 +26,9 @@ async function mintAgentPat(opts) {
26
26
  }
27
27
  return {
28
28
  plaintextToken: response.plaintextToken,
29
- id: response.token.id,
30
- name: response.token.name,
31
- expiresAt: response.token.expiresAt,
29
+ id: response.id,
30
+ name: response.name,
31
+ expiresAt: response.expiresAt,
32
32
  };
33
33
  }
34
34
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"pat-store.js","sourceRoot":"","sources":["../../src/lib/pat-store.ts"],"names":[],"mappings":";;AAoEA,oCA6BC;AAOD,sDAIC;AA5GD,qCAAmC;AACnC,6CAAmD;AAmE5C,KAAK,UAAU,YAAY,CAAC,IAAoB;IACtD,MAAM,IAAI,GAAG,IAAI,CAAC,YAAY,IAAI,qBAAqB,EAAE,CAAC;IAE1D,IAAI,QAA2B,CAAC;IAChC,IAAI,CAAC;QACJ,QAAQ,GAAG,MAAM,IAAI,CAAC,GAAG,CAAC,IAAI,CAAoB,cAAc,EAAE;YACjE,IAAI;YACJ,MAAM,EAAE,IAAI,CAAC,MAAM,IAAI,CAAC,OAAO,CAAC;YAChC,uDAAuD;YACvD,aAAa,EAAE,IAAI,CAAC,aAAa,IAAI,GAAG;SACxC,CAAC,CAAC;IACJ,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACd,IAAI,GAAG,YAAY,qBAAQ,IAAI,GAAG,CAAC,MAAM,KAAK,GAAG,EAAE,CAAC;YACnD,yDAAyD;YACzD,mDAAmD;YACnD,MAAM,IAAI,KAAK,CACd,8DAA8D;gBAC7D,uEAAuE,CACxE,CAAC;QACH,CAAC;QACD,MAAM,GAAG,CAAC;IACX,CAAC;IAED,OAAO;QACN,cAAc,EAAE,QAAQ,CAAC,cAAc;QACvC,EAAE,EAAE,QAAQ,CAAC,KAAK,CAAC,EAAE;QACrB,IAAI,EAAE,QAAQ,CAAC,KAAK,CAAC,IAAI;QACzB,SAAS,EAAE,QAAQ,CAAC,KAAK,CAAC,SAAS;KACnC,CAAC;AACH,CAAC;AAED;;;;GAIG;AACH,SAAgB,qBAAqB;IACpC,MAAM,IAAI,GAAG,IAAA,kBAAQ,GAAE,IAAI,cAAc,CAAC;IAC1C,MAAM,IAAI,GAAG,gBAAgB,IAAI,EAAE,CAAC;IACpC,OAAO,IAAI,CAAC,MAAM,GAAG,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC;AAC5D,CAAC"}
1
+ {"version":3,"file":"pat-store.js","sourceRoot":"","sources":["../../src/lib/pat-store.ts"],"names":[],"mappings":";;AA8EA,oCA6BC;AAOD,sDAIC;AAtHD,qCAAmC;AACnC,6CAAmD;AA6E5C,KAAK,UAAU,YAAY,CAAC,IAAoB;IACtD,MAAM,IAAI,GAAG,IAAI,CAAC,YAAY,IAAI,qBAAqB,EAAE,CAAC;IAE1D,IAAI,QAA2B,CAAC;IAChC,IAAI,CAAC;QACJ,QAAQ,GAAG,MAAM,IAAI,CAAC,GAAG,CAAC,IAAI,CAAoB,cAAc,EAAE;YACjE,IAAI;YACJ,MAAM,EAAE,IAAI,CAAC,MAAM,IAAI,CAAC,OAAO,CAAC;YAChC,uDAAuD;YACvD,aAAa,EAAE,IAAI,CAAC,aAAa,IAAI,GAAG;SACxC,CAAC,CAAC;IACJ,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACd,IAAI,GAAG,YAAY,qBAAQ,IAAI,GAAG,CAAC,MAAM,KAAK,GAAG,EAAE,CAAC;YACnD,yDAAyD;YACzD,mDAAmD;YACnD,MAAM,IAAI,KAAK,CACd,8DAA8D;gBAC7D,uEAAuE,CACxE,CAAC;QACH,CAAC;QACD,MAAM,GAAG,CAAC;IACX,CAAC;IAED,OAAO;QACN,cAAc,EAAE,QAAQ,CAAC,cAAc;QACvC,EAAE,EAAE,QAAQ,CAAC,EAAE;QACf,IAAI,EAAE,QAAQ,CAAC,IAAI;QACnB,SAAS,EAAE,QAAQ,CAAC,SAAS;KAC7B,CAAC;AACH,CAAC;AAED;;;;GAIG;AACH,SAAgB,qBAAqB;IACpC,MAAM,IAAI,GAAG,IAAA,kBAAQ,GAAE,IAAI,cAAc,CAAC;IAC1C,MAAM,IAAI,GAAG,gBAAgB,IAAI,EAAE,CAAC;IACpC,OAAO,IAAI,CAAC,MAAM,GAAG,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC;AAC5D,CAAC"}
@@ -0,0 +1,51 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getProjectConfigPath = getProjectConfigPath;
4
+ exports.loadProjectConfig = loadProjectConfig;
5
+ exports.saveProjectConfig = saveProjectConfig;
6
+ const node_fs_1 = require("node:fs");
7
+ const node_path_1 = require("node:path");
8
+ const PROJECT_CONFIG_DIRNAME = '.ritual';
9
+ const PROJECT_CONFIG_FILENAME = 'config.json';
10
+ function getProjectConfigPath(projectDir) {
11
+ return (0, node_path_1.join)(projectDir, PROJECT_CONFIG_DIRNAME, PROJECT_CONFIG_FILENAME);
12
+ }
13
+ /**
14
+ * Load the project config from disk. Returns null when the file
15
+ * doesn't exist OR is malformed — caller treats both as "no project
16
+ * config yet, prompt to create one".
17
+ */
18
+ function loadProjectConfig(projectDir) {
19
+ const p = getProjectConfigPath(projectDir);
20
+ if (!(0, node_fs_1.existsSync)(p))
21
+ return null;
22
+ try {
23
+ const raw = (0, node_fs_1.readFileSync)(p, 'utf-8');
24
+ const parsed = JSON.parse(raw);
25
+ // Reject unknown versions — older CLI seeing a v2 file should
26
+ // bail rather than write back a v1-shaped truncation. v1 is the
27
+ // only thing we accept today.
28
+ if (parsed.version !== 1)
29
+ return null;
30
+ if (!parsed.workspaceId || typeof parsed.workspaceId !== 'string')
31
+ return null;
32
+ return parsed;
33
+ }
34
+ catch {
35
+ return null;
36
+ }
37
+ }
38
+ /**
39
+ * Write the project config. Creates the .ritual/ directory if needed.
40
+ *
41
+ * Not chmod-restricted because (a) the file contains no secrets and
42
+ * (b) it's meant to be committed and readable by everyone on the
43
+ * repo team. The user-scoped credentials at ~/.config/ritual/ are
44
+ * the secret-bearing files.
45
+ */
46
+ function saveProjectConfig(projectDir, config) {
47
+ const p = getProjectConfigPath(projectDir);
48
+ (0, node_fs_1.mkdirSync)((0, node_path_1.dirname)(p), { recursive: true });
49
+ (0, node_fs_1.writeFileSync)(p, JSON.stringify(config, null, 2) + '\n', 'utf-8');
50
+ }
51
+ //# sourceMappingURL=project-config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"project-config.js","sourceRoot":"","sources":["../../src/lib/project-config.ts"],"names":[],"mappings":";;AA8CA,oDAEC;AAOD,8CAeC;AAUD,8CAIC;AApFD,qCAA6E;AAC7E,yCAA0C;AA0C1C,MAAM,sBAAsB,GAAG,SAAS,CAAC;AACzC,MAAM,uBAAuB,GAAG,aAAa,CAAC;AAE9C,SAAgB,oBAAoB,CAAC,UAAkB;IACtD,OAAO,IAAA,gBAAI,EAAC,UAAU,EAAE,sBAAsB,EAAE,uBAAuB,CAAC,CAAC;AAC1E,CAAC;AAED;;;;GAIG;AACH,SAAgB,iBAAiB,CAAC,UAAkB;IACnD,MAAM,CAAC,GAAG,oBAAoB,CAAC,UAAU,CAAC,CAAC;IAC3C,IAAI,CAAC,IAAA,oBAAU,EAAC,CAAC,CAAC;QAAE,OAAO,IAAI,CAAC;IAChC,IAAI,CAAC;QACJ,MAAM,GAAG,GAAG,IAAA,sBAAY,EAAC,CAAC,EAAE,OAAO,CAAC,CAAC;QACrC,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAkB,CAAC;QAChD,8DAA8D;QAC9D,gEAAgE;QAChE,8BAA8B;QAC9B,IAAI,MAAM,CAAC,OAAO,KAAK,CAAC;YAAE,OAAO,IAAI,CAAC;QACtC,IAAI,CAAC,MAAM,CAAC,WAAW,IAAI,OAAO,MAAM,CAAC,WAAW,KAAK,QAAQ;YAAE,OAAO,IAAI,CAAC;QAC/E,OAAO,MAAM,CAAC;IACf,CAAC;IAAC,MAAM,CAAC;QACR,OAAO,IAAI,CAAC;IACb,CAAC;AACF,CAAC;AAED;;;;;;;GAOG;AACH,SAAgB,iBAAiB,CAAC,UAAkB,EAAE,MAAqB;IAC1E,MAAM,CAAC,GAAG,oBAAoB,CAAC,UAAU,CAAC,CAAC;IAC3C,IAAA,mBAAS,EAAC,IAAA,mBAAO,EAAC,CAAC,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAC3C,IAAA,uBAAa,EAAC,CAAC,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,EAAE,OAAO,CAAC,CAAC;AACnE,CAAC"}
@@ -0,0 +1,80 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.detectRepoName = detectRepoName;
4
+ exports.parseRepoNameFromUrl = parseRepoNameFromUrl;
5
+ const node_child_process_1 = require("node:child_process");
6
+ const node_path_1 = require("node:path");
7
+ function detectRepoName(projectDir) {
8
+ const fromGit = tryGitRemote(projectDir);
9
+ if (fromGit)
10
+ return fromGit;
11
+ const basenameDetection = (0, node_path_1.basename)(projectDir) || 'untitled';
12
+ return {
13
+ name: basenameDetection,
14
+ source: 'cwd-basename',
15
+ };
16
+ }
17
+ function tryGitRemote(projectDir) {
18
+ let originUrl;
19
+ try {
20
+ // `cwd: projectDir` so the user's actual project's origin is what
21
+ // we read, not whichever directory the CLI happened to be run
22
+ // from. `stdio: 'pipe'` swallows stderr — we don't want
23
+ // "not a git repository" leaking to the user's terminal.
24
+ const out = (0, node_child_process_1.execSync)('git remote get-url origin', {
25
+ cwd: projectDir,
26
+ stdio: ['ignore', 'pipe', 'pipe'],
27
+ encoding: 'utf-8',
28
+ timeout: 2000, // git is usually instant; cap at 2s to be safe
29
+ });
30
+ originUrl = out.trim();
31
+ if (!originUrl)
32
+ return null;
33
+ }
34
+ catch {
35
+ // Not a git repo, or git missing, or no origin remote. Fall
36
+ // through to the basename path.
37
+ return null;
38
+ }
39
+ const parsed = parseRepoNameFromUrl(originUrl);
40
+ if (!parsed)
41
+ return null;
42
+ return {
43
+ name: parsed,
44
+ source: 'git-remote',
45
+ originUrl,
46
+ };
47
+ }
48
+ /**
49
+ * Pull the repo name out of any of these URL shapes:
50
+ *
51
+ * git@github.com:org/repo.git → repo
52
+ * git@gitlab.com:group/sub/repo.git → repo
53
+ * https://github.com/org/repo.git → repo
54
+ * https://github.com/org/repo → repo
55
+ * ssh://git@bitbucket.org/org/repo.git → repo
56
+ *
57
+ * Returns null on inputs we can't make sense of (the caller falls
58
+ * back to cwd basename in that case).
59
+ */
60
+ function parseRepoNameFromUrl(url) {
61
+ // Strip trailing .git first so we don't have to think about it.
62
+ const noGit = url.replace(/\.git$/, '');
63
+ // The repo name is whatever's after the last slash OR colon.
64
+ // `git@host:org/repo` → split on `:` to get the path, then take
65
+ // the last segment after the final `/`. Plain HTTPS URLs we just
66
+ // take basename of.
67
+ const afterColon = noGit.includes(':') ? noGit.split(':').pop() : noGit;
68
+ const lastSegment = afterColon.split('/').filter(Boolean).pop();
69
+ if (!lastSegment)
70
+ return null;
71
+ // Sanity: workspace names should be human-readable. If we got
72
+ // something with spaces or really odd characters, the caller can
73
+ // still ask the user before using it, but we'll at least let it
74
+ // through.
75
+ const trimmed = lastSegment.trim();
76
+ if (trimmed.length === 0)
77
+ return null;
78
+ return trimmed;
79
+ }
80
+ //# sourceMappingURL=repo-name.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"repo-name.js","sourceRoot":"","sources":["../../src/lib/repo-name.ts"],"names":[],"mappings":";;AAoCA,wCASC;AA6CD,oDAoBC;AA9GD,2DAA8C;AAC9C,yCAAqC;AAmCrC,SAAgB,cAAc,CAAC,UAAkB;IAChD,MAAM,OAAO,GAAG,YAAY,CAAC,UAAU,CAAC,CAAC;IACzC,IAAI,OAAO;QAAE,OAAO,OAAO,CAAC;IAE5B,MAAM,iBAAiB,GAAG,IAAA,oBAAQ,EAAC,UAAU,CAAC,IAAI,UAAU,CAAC;IAC7D,OAAO;QACN,IAAI,EAAE,iBAAiB;QACvB,MAAM,EAAE,cAAc;KACtB,CAAC;AACH,CAAC;AAED,SAAS,YAAY,CAAC,UAAkB;IACvC,IAAI,SAAiB,CAAC;IACtB,IAAI,CAAC;QACJ,kEAAkE;QAClE,8DAA8D;QAC9D,wDAAwD;QACxD,yDAAyD;QACzD,MAAM,GAAG,GAAG,IAAA,6BAAQ,EAAC,2BAA2B,EAAE;YACjD,GAAG,EAAE,UAAU;YACf,KAAK,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,CAAC;YACjC,QAAQ,EAAE,OAAO;YACjB,OAAO,EAAE,IAAI,EAAE,+CAA+C;SAC9D,CAAC,CAAC;QACH,SAAS,GAAG,GAAG,CAAC,IAAI,EAAE,CAAC;QACvB,IAAI,CAAC,SAAS;YAAE,OAAO,IAAI,CAAC;IAC7B,CAAC;IAAC,MAAM,CAAC;QACR,4DAA4D;QAC5D,gCAAgC;QAChC,OAAO,IAAI,CAAC;IACb,CAAC;IAED,MAAM,MAAM,GAAG,oBAAoB,CAAC,SAAS,CAAC,CAAC;IAC/C,IAAI,CAAC,MAAM;QAAE,OAAO,IAAI,CAAC;IAEzB,OAAO;QACN,IAAI,EAAE,MAAM;QACZ,MAAM,EAAE,YAAY;QACpB,SAAS;KACT,CAAC;AACH,CAAC;AAED;;;;;;;;;;;GAWG;AACH,SAAgB,oBAAoB,CAAC,GAAW;IAC/C,gEAAgE;IAChE,MAAM,KAAK,GAAG,GAAG,CAAC,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;IAExC,6DAA6D;IAC7D,gEAAgE;IAChE,iEAAiE;IACjE,oBAAoB;IACpB,MAAM,UAAU,GAAG,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,EAAG,CAAC,CAAC,CAAC,KAAK,CAAC;IACzE,MAAM,WAAW,GAAG,UAAU,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,GAAG,EAAE,CAAC;IAEhE,IAAI,CAAC,WAAW;QAAE,OAAO,IAAI,CAAC;IAE9B,8DAA8D;IAC9D,iEAAiE;IACjE,gEAAgE;IAChE,WAAW;IACX,MAAM,OAAO,GAAG,WAAW,CAAC,IAAI,EAAE,CAAC;IACnC,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IACtC,OAAO,OAAO,CAAC;AAChB,CAAC"}
@@ -0,0 +1,82 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.resolveProjectWorkspace = resolveProjectWorkspace;
4
+ const project_config_1 = require("./project-config");
5
+ const repo_name_1 = require("./repo-name");
6
+ const prompt_1 = require("./prompt");
7
+ async function resolveProjectWorkspace(opts) {
8
+ // ── 1. Already bound? ──────────────────────────────────────────
9
+ const existing = (0, project_config_1.loadProjectConfig)(opts.projectDir);
10
+ if (existing) {
11
+ return {
12
+ workspaceId: existing.workspaceId,
13
+ workspaceName: existing.workspaceName,
14
+ created: false,
15
+ };
16
+ }
17
+ // ── 2 or 3. Decide based on TTY. ───────────────────────────────
18
+ const interactive = !opts.nonInteractive && process.stdin.isTTY;
19
+ if (!interactive) {
20
+ // CI / scripted: don't prompt. Caller surfaces a hint.
21
+ return null;
22
+ }
23
+ const detection = (0, repo_name_1.detectRepoName)(opts.projectDir);
24
+ console.log('');
25
+ console.log(' No Ritual workspace is bound to this project yet.');
26
+ console.log(` Detected name: ${detection.name} (from ${detection.source}${detection.originUrl ? ` — ${detection.originUrl}` : ''})`);
27
+ let answer;
28
+ try {
29
+ answer = await (0, prompt_1.prompt)(` Create workspace "${detection.name}" for this project? (Y/n/<custom name>): `);
30
+ }
31
+ catch {
32
+ // stdin closed / Ctrl-D — treat as skip.
33
+ console.log('');
34
+ return null;
35
+ }
36
+ const trimmed = answer.trim();
37
+ // Skip patterns the user actually intends as "no".
38
+ if (/^(n|no)$/i.test(trimmed)) {
39
+ console.log(' Skipped workspace creation. You can bind one later with `ritual workspace bind`.');
40
+ return null;
41
+ }
42
+ // Resolve the final workspace name:
43
+ // - empty / "y" / "yes" → use the detected name
44
+ // - anything else → treat as a custom name override
45
+ let workspaceName;
46
+ if (trimmed === '' || /^(y|yes)$/i.test(trimmed)) {
47
+ workspaceName = detection.name;
48
+ }
49
+ else {
50
+ workspaceName = trimmed;
51
+ }
52
+ // ── Create the workspace via apps/api. ─────────────────────────
53
+ let created;
54
+ try {
55
+ created = await opts.api.post('/workspaces', {
56
+ name: workspaceName,
57
+ type: 'project',
58
+ });
59
+ }
60
+ catch (err) {
61
+ console.error(` ✗ Could not create workspace: ${err.message}`);
62
+ console.error(' Skipping workspace bind. Re-run `ritual init` to retry.');
63
+ return null;
64
+ }
65
+ // ── Persist to .ritual/config.json. ────────────────────────────
66
+ const config = {
67
+ version: 1,
68
+ workspaceId: created.id,
69
+ workspaceName: created.name,
70
+ createdAt: new Date().toISOString(),
71
+ };
72
+ (0, project_config_1.saveProjectConfig)(opts.projectDir, config);
73
+ console.log(` ✓ Created workspace "${created.name}" (id: ${created.id})`);
74
+ console.log(` ✓ Saved to .ritual/config.json — commit this file so your team uses the same workspace.`);
75
+ console.log('');
76
+ return {
77
+ workspaceId: created.id,
78
+ workspaceName: created.name,
79
+ created: true,
80
+ };
81
+ }
82
+ //# sourceMappingURL=workspace-flow.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"workspace-flow.js","sourceRoot":"","sources":["../../src/lib/workspace-flow.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ritualai/cli",
3
- "version": "0.3.2",
3
+ "version": "0.4.0",
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",
@@ -51,60 +51,161 @@ When **not** to use:
51
51
  - An exploration already exists with recommendations — fetch directly via `get_exploration` + `get_recommendations`
52
52
  - The user wants to *implement* a feature from existing recommendations — use `/ritual-builder-spec` (from `@ritual-ai/cli`)
53
53
 
54
- ### Workflow — 7 phases
54
+ ### Workflow — 8 phases
55
55
 
56
56
  Each phase has explicit **[USER PAUSE]** points — never skip them.
57
57
 
58
58
  #### Phase 1 — Pick a workspace
59
59
 
60
- Call `mcp__ritual__list_workspaces`. Present as a numbered list (id, name).
60
+ Resolution order:
61
61
 
62
- If the user only has one project workspace, confirm it directly: "I'll create this in *Acme Engineering*. Sound right?" — but still wait for **[USER PAUSE]**.
62
+ 1. **Project-bound workspace (preferred).** Check for a `.ritual/config.json` at the project root (you can use the Read tool — the file is a small JSON with `workspaceId` + `workspaceName`). If it exists, that's the workspace this repo is bound to. Surface it to the user: "Using workspace **`{workspaceName}`** (bound to this repo). Sound right?" — wait for **[USER PAUSE]**.
63
+ 2. **List existing project workspaces.** If no `.ritual/config.json`, call `mcp__ritual__list_workspaces` — this returns project-type workspaces (the General workspace is excluded by default; agents never use it). Present as a numbered list (id, name). **[USER PAUSE]** for selection.
64
+ 3. **Create a new one if none exist or user wants a fresh one.** Call `mcp__ritual__create_workspace` with a name — convention is to name it after the repo (basename of cwd, or origin remote). Confirm the name with the user first. **[USER PAUSE]**
63
65
 
64
- Store `workspace_id`.
66
+ Store `workspace_id` for the rest of the flow.
67
+
68
+ If you created a new workspace, suggest the user run `ritual init` to persist the binding into `.ritual/config.json` for next time (or write it yourself if the user is in a Claude Code session that can edit files).
69
+
70
+ #### Phase 1.5 — Code reconnaissance
71
+
72
+ **Skip only if the user explicitly asks ("just generate, don't read the code") OR if you're operating outside a codebase context.**
73
+
74
+ Before generating considerations, do a structured scan of the codebase so the sub-problems land specific to *this* code, not generic. The legacy system shipped considerations that read like a textbook table of contents because it skipped this step; the difference between "Conversion Timing, Trust Signals, Recovery Paths" (generic) and "Leverage `apps/checkout/session.py` anonymous-checkout path vs. adding a new step in `CheckoutSessionMixin`" (codebase-specific) is whether you did Phase 1.5.
75
+
76
+ Steps:
77
+
78
+ 1. **Read the README + top-level project structure.** Use `ls` / Glob to see top-level files (5–10 lines). Identify the language, framework, key directories.
79
+
80
+ 2. **Glob for relevance.** Derive patterns from the user's problem. Examples:
81
+ - User says "auth flow" → `**/auth/**`, `**/login*`, `**/user*`, `**/session*`
82
+ - User says "checkout" → `**/checkout/**`, `**/cart/**`, `**/order/**`, `**/payment*`
83
+ - User says "notifications" → `**/notif*`, `**/email/**`, `**/sms/**`, `**/push/**`
84
+ Cap at ~15 hits per pattern.
85
+
86
+ 3. **Skim 3–5 most-relevant files.** For each, read the first ~100 lines + scan for class/function names. Triangulate: "is the behavior we care about actually here, or does it call into somewhere else?"
87
+
88
+ 4. **Build a recon summary** — 5–10 lines, concrete file paths, key abstractions, observed constraints. Examples of GOOD summaries:
89
+
90
+ > Codebase recon (django-oscar, Django 5.0):
91
+ > - Booking flow lives in `apps/checkout/views.py` (`CheckoutSessionMixin` orchestrates the step chain)
92
+ > - Anonymous checkout already supported via `apps/checkout/session.py:CheckoutSessionData`
93
+ > - Account creation entry point: `apps/customer/forms.py:RegisterUserForm`
94
+ > - Strategy classes (`apps/partner/strategy.py`) are the conventional pluggability pattern
95
+ > - User-model split: `auth.User` is the Django auth user; `apps/customer/models.py:Customer` is the order-attached profile — they can be linked or anonymous
96
+
97
+ 5. **Surface to the user as a [USER PAUSE]**:
98
+
99
+ > Reading the codebase I see:
100
+ > <recon summary>
101
+ >
102
+ > Anything I'm missing about design intent or constraints I won't find by reading the code (e.g. business decisions, prod incidents, in-flight migrations)?
103
+
104
+ Wait for confirmation or additional context. The user's reply (if any) becomes part of the input to Phase 2.
105
+
106
+ 6. **Compose the augmented `raw_input` for Phase 2.** Concatenate:
107
+ - The user's original problem (verbatim, top)
108
+ - A `--- Codebase context ---` section with the recon summary
109
+ - The user's reply from step 5 if non-empty
110
+ - Phase 1.5 IS the difference between "generic considerations" and "considerations that name actual files and reference existing patterns". Don't skip the recon step. Don't compress the summary to one line.
111
+
112
+ 7. **Collect the `sources` array.** The file paths you read in step 3 — exactly as they appear in the repo (e.g. `"apps/checkout/views.py"`, NOT `"./apps/checkout/views.py"` or absolute paths). This list is passed alongside `raw_input` to `generate_considerations` and `generate_problem_statement` so the API can auto-inject **prior knowledge-graph context** for overlapping files. Keep the list focused — only files you actually read and consider load-bearing for this problem. 5–10 is the sweet spot; >20 dilutes the KG signal.
113
+
114
+ **[USER PAUSE]** confirmation of recon is required before proceeding.
65
115
 
66
116
  #### Phase 2 — Generate sub-problems
67
117
 
118
+ ##### 2.1 First draft
119
+
68
120
  Call `mcp__ritual__generate_considerations` with:
69
121
  - `workspace_id`
70
- - `raw_input` (the problem from the slash-command argument or chat)
122
+ - `raw_input` (the user's problem + the Phase 1.5 codebase recon, concatenated as described above)
71
123
  - `template_id` (omit unless the user specified one)
124
+ - `sources` (the file path list from Phase 1.5 step 7 — file-path strings only, e.g. `["apps/checkout/views.py", ...]`)
72
125
 
73
- LLM call, ~5-10s. Returns 5-6 sub-problems — different framing axes the agent should investigate.
126
+ LLM call, ~510s. Returns 56 sub-problems — different framing axes the agent should investigate. Track each one as `{ text, version: 1 }` in your working memory.
127
+
128
+ **If the response includes `kg_context_used` with `implementationCount > 0`:** surface this to the user BEFORE presenting the considerations. It's the visible signal that prior team decisions shaped this draft.
129
+
130
+ > Reading the codebase I overlapped with 3 prior Ritual explorations on these files:
131
+ > - **"Anonymous checkout opt-in"** (shipped 2026-04-12) — 2 decisions, 1 deferral
132
+ > - **"Payment-method routing"** (shipped 2026-03-22) — 4 decisions
133
+ > - **"Session-data persistence"** (shipped 2026-02-08) — 1 decision
134
+ >
135
+ > I factored those into the sub-problems below.
136
+
137
+ If `implementationCount === 0`: don't mention the KG check (silent — would just be noise on a cold KG).
74
138
 
75
139
  **[USER PAUSE]** Present as a numbered list and ask which to include:
76
140
 
77
- > Sub-problems the system identified:
141
+ > Sub-problems the system identified (v1):
78
142
  >
79
143
  > 1. {sub-problem 1}
80
144
  > 2. {sub-problem 2}
81
145
  > ...
82
146
  >
83
- > Which should we factor into the scope? Pick any subset, or "all".
147
+ > Which should we factor into the scope? Pick any subset, "all", or ask for a different framing (e.g. "make them more technical", "drop the measurement angle", "focus on enterprise").
148
+
149
+ ##### 2.2 Iteration loop
150
+
151
+ If the user asks for a refinement (anything that isn't "all" / specific picks / "these are good"):
152
+
153
+ Call `mcp__ritual__refine_considerations` with:
154
+ - `workspace_id`, `raw_input`, `template_id`, `sources` — unchanged from the generate call. Critical: pass the SAME `sources` array each iteration so the KG-injected priorContext stays consistent.
155
+ - `change_prompt`: the user's request verbatim
156
+ - `selected`: items from prior versions the user kept (track `{ text, from_version }`, send just `text`)
157
+ - `dismissed`: items the user explicitly rejected
158
+ - `session_id`: omitted on the first refinement; pass the `session_id` from the previous refine response on subsequent ones to chain context
159
+
160
+ Track the new items as `{ text, version: N+1 }`. Present **alongside** the prior versions, not replacing them — the user can mix selections across versions.
161
+
162
+ Loop until the user says "these are good" or picks a subset.
84
163
 
85
- Store the picked sub-problems (text strings they'll go into `considerations[]` next call).
164
+ **Critical**: never re-call `generate_considerations` for a refinement. That endpoint is stateless and re-rolls a fresh seed; you'll lose what the user just told you. The whole point of `refine_*` is the LLM sees the iteration context.
165
+
166
+ Store the final picked sub-problems for Phase 3 — they go into `considerations[]`.
86
167
 
87
168
  #### Phase 3 — Generate scope
88
169
 
170
+ ##### 3.1 First draft
171
+
89
172
  Call `mcp__ritual__generate_problem_statement` with:
90
173
  - `workspace_id`
91
- - `raw_input`
92
- - `considerations` (the picks from Phase 2 — these are the sub-problems we just discussed)
174
+ - `raw_input` (same augmented version from Phase 2)
175
+ - `considerations` (the picks from Phase 2)
93
176
  - `template_id` (same as Phase 2 if used)
177
+ - `sources` (the same file-path list passed to generate_considerations — keeps the KG anchor consistent)
178
+
179
+ Returns a polished "How might we ..." style scope (typically <800 chars) plus optional follow-up questions and quality scores. Treat this as **v1** of the problem statement.
180
+
181
+ If the response includes `kg_context_used` with `implementationCount > 0`, prepend a note to the scope presentation:
94
182
 
95
- Returns a polished "How might we ..." style scope (typically <800 chars) plus optional follow-up questions and quality scores.
183
+ > *(Grounded in {N} prior implementation{s}: {top match name}, )*
96
184
 
97
185
  **[USER PAUSE]** Present and ask:
98
186
 
99
- > Here's the scope:
187
+ > Here's the scope (v1):
100
188
  >
101
189
  > > **{generated scope}**
102
190
  >
103
- > Looks good? Want to tighten / broaden / change the audience? Or "ship it" to lock it in.
191
+ > Looks good? Want to tighten / broaden / change the audience / focus on a specific tier? Or "ship it" to lock it in.
192
+
193
+ ##### 3.2 Iteration loop
194
+
195
+ If the user asks for a refinement:
196
+
197
+ Call `mcp__ritual__refine_problem_statement` with:
198
+ - `workspace_id`, `raw_input`, `considerations`, `template_id`, `sources` — unchanged. (Same `sources` as the original generate call — keeps the KG anchor stable.)
199
+ - `previous_problem_statement`: the FULL TEXT of the current best draft (the v1 you just showed)
200
+ - `change_prompt`: the user's request verbatim ("tighten and drop the audience clause")
201
+ - `version`: optional label like `"v2"` — purely for telemetry
202
+ - `session_id`: omitted on the first refinement; chain on subsequent ones
203
+
204
+ The returned text becomes `v2`. Show it. The user can iterate v2 → v3 → ... by calling refine again with `previous_problem_statement` set to the latest draft.
104
205
 
105
- If refinement requested: regenerate with the refinement appended to `raw_input`. Iterate until accepted.
206
+ **Critical**: each refinement's `previous_problem_statement` is the LATEST draft, not the original v1. Otherwise the LLM keeps refining the same starting point and the user can't compose multiple refinements ("tighter, AND drop the audience clause, AND make it past-tense").
106
207
 
107
- Store the final scope as `problem_statement` for the next call.
208
+ When the user accepts ("ship it" / "looks good"), store the final text as `problem_statement` for Phase 4.
108
209
 
109
210
  #### Phase 4 — Create the exploration
110
211