@ranger-testing/ranger-cli 1.1.7 → 2.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (90) hide show
  1. package/README.md +47 -45
  2. package/build/cli.js +649 -277
  3. package/build/cli.js.map +1 -1
  4. package/build/commands/addEnv.js +1 -1
  5. package/build/commands/addEnv.js.map +1 -1
  6. package/build/commands/authEncrypt.js +5 -10
  7. package/build/commands/authEncrypt.js.map +1 -1
  8. package/build/commands/clean.js +1 -1
  9. package/build/commands/clean.js.map +1 -1
  10. package/build/commands/config.js +9 -15
  11. package/build/commands/config.js.map +1 -1
  12. package/build/commands/env.js +10 -13
  13. package/build/commands/env.js.map +1 -1
  14. package/build/commands/feature.js +174 -123
  15. package/build/commands/feature.js.map +1 -1
  16. package/build/commands/hooks/autoPrompt.js +1 -1
  17. package/build/commands/hooks/disable.js +1 -1
  18. package/build/commands/hooks/enable.js +9 -4
  19. package/build/commands/hooks/enable.js.map +1 -1
  20. package/build/commands/hooks/exitPlanMode.js +8 -8
  21. package/build/commands/hooks/planReminder.js +7 -7
  22. package/build/commands/hooks/planStart.js +4 -4
  23. package/build/commands/hooks/postEdit.js +4 -4
  24. package/build/commands/hooks/postEdit.js.map +1 -1
  25. package/build/commands/hooks/preCompact.js +3 -3
  26. package/build/commands/hooks/preCompact.js.map +1 -1
  27. package/build/commands/hooks/sessionStart.js +19 -5
  28. package/build/commands/hooks/sessionStart.js.map +1 -1
  29. package/build/commands/hooks/stopHook.js +114 -20
  30. package/build/commands/hooks/stopHook.js.map +1 -1
  31. package/build/commands/index.js +1 -2
  32. package/build/commands/index.js.map +1 -1
  33. package/build/commands/login.js +2 -5
  34. package/build/commands/login.js.map +1 -1
  35. package/build/commands/setupCi.js +189 -0
  36. package/build/commands/setupCi.js.map +1 -0
  37. package/build/commands/skillup.js +16 -68
  38. package/build/commands/skillup.js.map +1 -1
  39. package/build/commands/start.js +1 -1
  40. package/build/commands/start.js.map +1 -1
  41. package/build/commands/status.js +14 -13
  42. package/build/commands/status.js.map +1 -1
  43. package/build/commands/update.js +52 -5
  44. package/build/commands/update.js.map +1 -1
  45. package/build/commands/updateEnv.js +1 -1
  46. package/build/commands/updateEnv.js.map +1 -1
  47. package/build/commands/useEnv.js +1 -1
  48. package/build/commands/useEnv.js.map +1 -1
  49. package/build/commands/utils/activeProfile.js +76 -0
  50. package/build/commands/utils/activeProfile.js.map +1 -0
  51. package/build/commands/utils/browserSessionsApi.js +1 -1
  52. package/build/commands/utils/browserSessionsApi.js.map +1 -1
  53. package/build/commands/utils/deviceAuth.js +53 -5
  54. package/build/commands/utils/deviceAuth.js.map +1 -1
  55. package/build/commands/utils/environment.js +11 -12
  56. package/build/commands/utils/environment.js.map +1 -1
  57. package/build/commands/utils/featureApi.js +55 -30
  58. package/build/commands/utils/featureApi.js.map +1 -1
  59. package/build/commands/utils/featureReportGenerator.js +6 -6
  60. package/build/commands/utils/featureReportGenerator.js.map +1 -1
  61. package/build/commands/utils/keychain.js +1 -1
  62. package/build/commands/utils/localAgentInstallationsApi.js +1 -1
  63. package/build/commands/utils/profileMessages.js +8 -0
  64. package/build/commands/utils/profileMessages.js.map +1 -0
  65. package/build/commands/utils/profileSetupBanner.js +167 -0
  66. package/build/commands/utils/profileSetupBanner.js.map +1 -0
  67. package/build/commands/utils/settings.js +20 -2
  68. package/build/commands/utils/settings.js.map +1 -1
  69. package/build/commands/utils/skills.js +1 -1
  70. package/build/commands/utils/telemetry.js +254 -0
  71. package/build/commands/utils/telemetry.js.map +1 -0
  72. package/build/commands/utils/userApi.js +4 -4
  73. package/build/commands/utils/userApi.js.map +1 -1
  74. package/build/commands/verifyFeature.js +816 -526
  75. package/build/commands/verifyFeature.js.map +1 -1
  76. package/build/commands/verifyInBrowser.js +1 -1
  77. package/build/commands/verifyInBrowser.js.map +1 -1
  78. package/build/skills/ranger/SKILL.md +65 -64
  79. package/build/skills/ranger/create.md +31 -31
  80. package/build/skills/ranger/feedback.md +25 -17
  81. package/build/skills/ranger/start.md +37 -37
  82. package/build/skills/ranger/verify.md +59 -55
  83. package/package.json +1 -1
  84. package/scripts/postinstall.js +1 -1
  85. package/build/commands/dataMcpServer.js +0 -1
  86. package/build/commands/dataMcpServer.js.map +0 -1
  87. package/build/commands/utils/cliSecret.js +0 -1
  88. package/build/commands/utils/cliSecret.js.map +0 -1
  89. package/build/skills/bug-bash.md +0 -329
  90. package/build/skills/e2e-test-recommender.md +0 -168
@@ -4,7 +4,7 @@ const AUTO_PROMPT_TEXT = `
4
4
  🚨 🚨 [ACTION REQUIRED] 🚨 🚨
5
5
  Before responding to the user's message, consider whether this task will involve ANY frontend, UI, or browser work.
6
6
  If so, you MUST first ask them:
7
- "Would you like to enable Ranger Feature Review for this session? It verifies features and user workflows in a real browser while Claude works."
7
+ "Would you like to enable Ranger Feature Review for this session? It verifies feature review scenarios and user workflows in a real browser while Claude works."
8
8
  Asking this question is ABSOLUTELY ESSENTIAL. DO NOT SKIP THIS STEP.
9
9
  If they say yes, run \`ranger hook enable\` (Bash tool).
10
10
  If they say no, say "Sounds good. If you change your mind, you can enable it with /ranger:enable" and then proceed with their request.
@@ -26,7 +26,7 @@ The user has expressly disabled Ranger hooks for this session${branch && branch
26
26
  **IMPORTANT INSTRUCTIONS:**
27
27
  - Do NOT use the /ranger skill
28
28
  - Do NOT use any \`ranger\` CLI commands
29
- - Proceed with your task without tracking features using the Ranger CLI
29
+ - Proceed with your task without tracking feature reviews using the Ranger CLI
30
30
 
31
31
  To re-enable Ranger, run \`/ranger:enable\`.`);
32
32
  }
@@ -24,13 +24,18 @@ The Ranger CLI is not configured. To get started:
24
24
 
25
25
  1. Install: \`npm install -g @ranger-testing/ranger-cli\`
26
26
  2. Get token: https://dashboard.ranger.net/cli
27
- 3. Initialize: \`ranger start <your-token>\`
27
+ 3. Initialize: \`ranger setup [token]\`
28
28
 
29
29
  Restart your Claude Code session after setup.`);
30
30
  return;
31
31
  }
32
32
  // Run ranger update to ensure CLI and skills are up to date
33
- await update();
33
+ try {
34
+ await update();
35
+ }
36
+ catch {
37
+ // Non-fatal — don't block hook enablement if update check fails
38
+ }
34
39
  // Enable hooks for this session (and auto-enable branch if not on main)
35
40
  enableSession(sessionId);
36
41
  const branch = getCurrentBranch();
@@ -47,7 +52,7 @@ ${skillContent}
47
52
 
48
53
  ## Quick Reference
49
54
 
50
- **In plan mode:** Include Ranger Feature Specification at end of plan.
51
- **Not in plan mode:** Run \`ranger feature create\` FIRST, then verify with \`ranger verify-feature\`.`);
55
+ **In plan mode:** Include Ranger Feature Review Specification at end of plan.
56
+ **Not in plan mode:** Run \`ranger create\` FIRST, then verify with \`ranger go\`.`);
52
57
  }
53
58
  //# sourceMappingURL=enable.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"enable.js","sourceRoot":"","sources":["../../../src/commands/hooks/enable.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAC3E,OAAO,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAChD,OAAO,EAAE,qBAAqB,EAAE,MAAM,0BAA0B,CAAC;AACjE,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAEtC;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,MAAM,CAAC,iBAA0B;IACnD,MAAM,SAAS,GAAG,iBAAiB,IAAI,OAAO,CAAC,GAAG,CAAC,iBAAiB,IAAI,EAAE,CAAC;IAE3E,IAAI,CAAC,SAAS,EAAE,CAAC;QACb,OAAO,CAAC,KAAK,CAAC,iCAAiC,CAAC,CAAC;QACjD,OAAO,CAAC,KAAK,CACT,0DAA0D,CAC7D,CAAC;QACF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACpB,CAAC;IAED,yCAAyC;IACzC,MAAM,KAAK,GAAG,MAAM,QAAQ,EAAE,CAAC;IAC/B,IAAI,CAAC,KAAK,EAAE,CAAC;QACT,UAAU,CAAC;;;;;;;;8CAQ2B,CAAC,CAAC;QACxC,OAAO;IACX,CAAC;IAED,4DAA4D;IAC5D,MAAM,MAAM,EAAE,CAAC;IAEf,wEAAwE;IACxE,aAAa,CAAC,SAAS,CAAC,CAAC;IAEzB,MAAM,MAAM,GAAG,gBAAgB,EAAE,CAAC;IAClC,MAAM,UAAU,GACZ,MAAM,IAAI,MAAM,KAAK,MAAM,IAAI,MAAM,KAAK,QAAQ;QAC9C,CAAC,CAAC,iBAAiB,MAAM,8EAA8E;QACvG,CAAC,CAAC,EAAE,CAAC;IAEb,0BAA0B;IAC1B,MAAM,YAAY,GAAG,qBAAqB,EAAE,CAAC;IAE7C,UAAU,CAAC,mBAAmB,UAAU;;;;EAI1C,YAAY;;;;;uGAKyF,CAAC,CAAC;AACzG,CAAC"}
1
+ {"version":3,"file":"enable.js","sourceRoot":"","sources":["../../../src/commands/hooks/enable.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAC3E,OAAO,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAChD,OAAO,EAAE,qBAAqB,EAAE,MAAM,0BAA0B,CAAC;AACjE,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAEtC;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,MAAM,CAAC,iBAA0B;IACnD,MAAM,SAAS,GAAG,iBAAiB,IAAI,OAAO,CAAC,GAAG,CAAC,iBAAiB,IAAI,EAAE,CAAC;IAE3E,IAAI,CAAC,SAAS,EAAE,CAAC;QACb,OAAO,CAAC,KAAK,CAAC,iCAAiC,CAAC,CAAC;QACjD,OAAO,CAAC,KAAK,CACT,0DAA0D,CAC7D,CAAC;QACF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACpB,CAAC;IAED,yCAAyC;IACzC,MAAM,KAAK,GAAG,MAAM,QAAQ,EAAE,CAAC;IAC/B,IAAI,CAAC,KAAK,EAAE,CAAC;QACT,UAAU,CAAC;;;;;;;;8CAQ2B,CAAC,CAAC;QACxC,OAAO;IACX,CAAC;IAED,4DAA4D;IAC5D,IAAI,CAAC;QACD,MAAM,MAAM,EAAE,CAAC;IACnB,CAAC;IAAC,MAAM,CAAC;QACL,gEAAgE;IACpE,CAAC;IAED,wEAAwE;IACxE,aAAa,CAAC,SAAS,CAAC,CAAC;IAEzB,MAAM,MAAM,GAAG,gBAAgB,EAAE,CAAC;IAClC,MAAM,UAAU,GACZ,MAAM,IAAI,MAAM,KAAK,MAAM,IAAI,MAAM,KAAK,QAAQ;QAC9C,CAAC,CAAC,iBAAiB,MAAM,8EAA8E;QACvG,CAAC,CAAC,EAAE,CAAC;IAEb,0BAA0B;IAC1B,MAAM,YAAY,GAAG,qBAAqB,EAAE,CAAC;IAE7C,UAAU,CAAC,mBAAmB,UAAU;;;;EAI1C,YAAY;;;;;mFAKqE,CAAC,CAAC;AACrF,CAAC"}
@@ -3,32 +3,32 @@ import { printBlock, getEnabledSessionId } from './output.js';
3
3
  * PermissionRequest hook handler for ExitPlanMode
4
4
  *
5
5
  * This command is invoked when Claude requests permission to exit plan mode.
6
- * It reminds Claude to create a Ranger feature to track the work.
6
+ * It reminds Claude to create a Ranger feature review to track the work.
7
7
  */
8
8
  export async function exitPlanMode(sessionIdOverride) {
9
9
  const sessionId = await getEnabledSessionId(sessionIdOverride);
10
10
  if (!sessionId) {
11
11
  return;
12
12
  }
13
- printBlock(`=== RANGER: CREATE FEATURE NOW ===
13
+ printBlock(`=== RANGER: CREATE FEATURE REVIEW NOW ===
14
14
 
15
15
  You are about to exit plan mode. If your plan includes UI changes:
16
16
 
17
- **ACTION REQUIRED:** Create the Ranger feature using items from your Ranger Feature Specification:
17
+ **ACTION REQUIRED:** Create the Ranger feature review using scenarios from your Ranger Feature Review Specification:
18
18
 
19
19
  \`\`\`
20
- ranger feature create "<Feature Name from plan>" \\
20
+ ranger create "<Feature Review Name from plan>" \\
21
21
  -d "<Description from plan>" \\
22
- -c "<Checklist item 1 from plan>" \\
23
- -c "<Checklist item 2 from plan>"
22
+ -c "<Scenario 1 from plan>" \\
23
+ -c "<Scenario 2 from plan>"
24
24
  \`\`\`
25
25
 
26
- **REMINDER:** Checklist items must be E2E user flows, NOT implementation tasks.
26
+ **REMINDER:** Scenarios must be E2E user flows, NOT implementation tasks.
27
27
 
28
28
  **Good:** "User can log in with valid credentials and see dashboard"
29
29
  **Bad:** "Add form validation" or "API returns 200"
30
30
 
31
- If you did NOT include a Ranger Feature Specification in your plan, go back and add one before proceeding. See /ranger and create.md for guidance.
31
+ If you did NOT include a Ranger Feature Review Specification in your plan, go back and add one before proceeding. See /ranger and create.md for guidance.
32
32
 
33
33
  === END ===`);
34
34
  }
@@ -24,22 +24,22 @@ export async function planReminder(sessionIdOverride) {
24
24
  If this plan involves ANY UI changes, you MUST:
25
25
 
26
26
  1. **READ /ranger skill NOW** - specifically the create.md instructions
27
- 2. **Add a Ranger Feature Specification** to the end of your plan
27
+ 2. **Add a Ranger Feature Review Specification** to the end of your plan
28
28
 
29
- DO NOT write checklist items without reading create.md first.
30
- Checklist items are E2E test scenarios, NOT implementation tasks.
29
+ DO NOT write scenarios without reading create.md first.
30
+ Scenarios are E2E test flows, NOT implementation tasks.
31
31
 
32
32
  Your plan must end with:
33
33
  \`\`\`
34
- ### Ranger Feature Specification (create this first with \`ranger feature create\`)
35
- Feature Name: <name>
34
+ ### Ranger Feature Review Specification (create this first with \`ranger create\`)
35
+ Feature Review Name: <name>
36
36
  Description: <description>
37
- Checklist:
37
+ Scenarios:
38
38
  1. <E2E user flow that can be verified in browser>
39
39
  2. <another E2E user flow if needed>
40
40
  \`\`\`
41
41
 
42
- Then run: \`ranger feature create "<name>" -d "<desc>" -c "<item1>" -c "<item2>"\`
42
+ Then run: \`ranger create "<name>" -d "<desc>" -c "<scenario1>" -c "<scenario2>"\`
43
43
 
44
44
  === END ===`);
45
45
  }
@@ -3,7 +3,7 @@ import { printBlock, getEnabledSessionId } from './output.js';
3
3
  * SubagentStart hook handler for Plan mode
4
4
  *
5
5
  * This command is invoked when Claude enters plan mode (Plan subagent starts).
6
- * It reminds Claude to include Ranger checklist items as part of the planning process.
6
+ * It reminds Claude to include Ranger scenarios as part of the planning process.
7
7
  */
8
8
  export async function planStart(sessionIdOverride) {
9
9
  const sessionId = await getEnabledSessionId(sessionIdOverride);
@@ -15,15 +15,15 @@ export async function planStart(sessionIdOverride) {
15
15
  If this plan involves UI changes, you MUST:
16
16
 
17
17
  1. **READ /ranger skill** - specifically create.md
18
- 2. **Add a Ranger Feature Specification** at the end of your plan
18
+ 2. **Add a Ranger Feature Review Specification** at the end of your plan
19
19
 
20
- Checklist items are E2E test scenarios, NOT implementation tasks.
20
+ Scenarios are E2E test flows, NOT implementation tasks.
21
21
 
22
22
  **Good:** "User can log in with valid credentials and see dashboard"
23
23
  **Bad:** "Add form validation" or "Button is visible"
24
24
 
25
25
  After planning, run:
26
- \`ranger feature create "<name>" -d "<desc>" -c "<E2E flow 1>" -c "<E2E flow 2>"\`
26
+ \`ranger create "<name>" -d "<desc>" -c "<E2E flow 1>" -c "<E2E flow 2>"\`
27
27
 
28
28
  === END ===`);
29
29
  }
@@ -5,7 +5,7 @@ import { getEnabledSessionId } from './output.js';
5
5
  * PostToolUse (Write/Edit) hook handler for Claude Code plugin
6
6
  *
7
7
  * This command is invoked automatically after Write or Edit tools are used.
8
- * If the session isn't registered with a Ranger feature, prompts to use /ranger.
8
+ * If the session isn't registered with a Ranger feature review, prompts to use /ranger.
9
9
  */
10
10
  export async function postEdit(sessionIdOverride) {
11
11
  const sessionId = await getEnabledSessionId(sessionIdOverride);
@@ -21,11 +21,11 @@ export async function postEdit(sessionIdOverride) {
21
21
  // Check if this session is already registered
22
22
  const existingEntry = getSessionEntry(sessionId);
23
23
  if (existingEntry) {
24
- // Already registered - remind about adding checklist items if scope expanded
24
+ // Already registered - remind about adding scenarios if scope expanded
25
25
  const response = {
26
26
  hookSpecificOutput: {
27
27
  hookEventName: 'PostToolUse',
28
- additionalContext: `RANGER: If this change expands the scope of the active feature, you may need to add a checklist item. See Workflow 1 in /ranger. If you decide to add a checklist item, you MUST read Workflow 1 IN DETAIL first.`,
28
+ additionalContext: `RANGER: If this change expands the scope of the active feature review, you may need to add a scenario. See Workflow 1 in /ranger. If you decide to add a scenario, you MUST read Workflow 1 IN DETAIL first.`,
29
29
  },
30
30
  };
31
31
  console.log(JSON.stringify(response));
@@ -35,7 +35,7 @@ export async function postEdit(sessionIdOverride) {
35
35
  const response = {
36
36
  hookSpecificOutput: {
37
37
  hookEventName: 'PostToolUse',
38
- additionalContext: `RANGER: If this is for a UI feature, you MUST use /ranger to either create a new feature or resume an existing one.`,
38
+ additionalContext: `RANGER: If this is for a UI feature, you MUST use /ranger to either create a new feature review or resume an existing one.`,
39
39
  },
40
40
  };
41
41
  console.log(JSON.stringify(response));
@@ -1 +1 @@
1
- {"version":3,"file":"postEdit.js","sourceRoot":"","sources":["../../../src/commands/hooks/postEdit.ts"],"names":[],"mappings":"AAAA,OAAO,EACH,eAAe,EACf,oBAAoB,GACvB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAChD,OAAO,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAElD;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,QAAQ,CAAC,iBAA0B;IACrD,MAAM,SAAS,GAAG,MAAM,mBAAmB,CAAC,iBAAiB,CAAC,CAAC;IAC/D,IAAI,CAAC,SAAS,EAAE,CAAC;QACb,OAAO;IACX,CAAC;IAED,sFAAsF;IACtF,oBAAoB,CAAC,SAAS,CAAC,CAAC;IAEhC,MAAM,KAAK,GAAG,MAAM,QAAQ,EAAE,CAAC;IAC/B,IAAI,CAAC,KAAK,EAAE,CAAC;QACT,OAAO;IACX,CAAC;IAED,8CAA8C;IAC9C,MAAM,aAAa,GAAG,eAAe,CAAC,SAAS,CAAC,CAAC;IACjD,IAAI,aAAa,EAAE,CAAC;QAChB,6EAA6E;QAC7E,MAAM,QAAQ,GAAG;YACb,kBAAkB,EAAE;gBAChB,aAAa,EAAE,aAAa;gBAC5B,iBAAiB,EAAE,mNAAmN;aACzO;SACJ,CAAC;QACF,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC,CAAC;QACtC,OAAO;IACX,CAAC;IAED,qDAAqD;IACrD,MAAM,QAAQ,GAAG;QACb,kBAAkB,EAAE;YAChB,aAAa,EAAE,aAAa;YAC5B,iBAAiB,EAAE,qHAAqH;SAC3I;KACJ,CAAC;IACF,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC,CAAC;AAC1C,CAAC"}
1
+ {"version":3,"file":"postEdit.js","sourceRoot":"","sources":["../../../src/commands/hooks/postEdit.ts"],"names":[],"mappings":"AAAA,OAAO,EACH,eAAe,EACf,oBAAoB,GACvB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAChD,OAAO,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAElD;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,QAAQ,CAAC,iBAA0B;IACrD,MAAM,SAAS,GAAG,MAAM,mBAAmB,CAAC,iBAAiB,CAAC,CAAC;IAC/D,IAAI,CAAC,SAAS,EAAE,CAAC;QACb,OAAO;IACX,CAAC;IAED,sFAAsF;IACtF,oBAAoB,CAAC,SAAS,CAAC,CAAC;IAEhC,MAAM,KAAK,GAAG,MAAM,QAAQ,EAAE,CAAC;IAC/B,IAAI,CAAC,KAAK,EAAE,CAAC;QACT,OAAO;IACX,CAAC;IAED,8CAA8C;IAC9C,MAAM,aAAa,GAAG,eAAe,CAAC,SAAS,CAAC,CAAC;IACjD,IAAI,aAAa,EAAE,CAAC;QAChB,uEAAuE;QACvE,MAAM,QAAQ,GAAG;YACb,kBAAkB,EAAE;gBAChB,aAAa,EAAE,aAAa;gBAC5B,iBAAiB,EAAE,8MAA8M;aACpO;SACJ,CAAC;QACF,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC,CAAC;QACtC,OAAO;IACX,CAAC;IAED,qDAAqD;IACrD,MAAM,QAAQ,GAAG;QACb,kBAAkB,EAAE;YAChB,aAAa,EAAE,aAAa;YAC5B,iBAAiB,EAAE,4HAA4H;SAClJ;KACJ,CAAC;IACF,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC,CAAC;AAC1C,CAAC"}
@@ -4,7 +4,7 @@ import { printBlock, getEnabledSessionId } from './output.js';
4
4
  * PreCompact hook handler for Claude Code plugin
5
5
  *
6
6
  * This command is invoked automatically before Claude Code compacts the conversation.
7
- * It reminds Claude to preserve Ranger Feature Specification in the compaction summary.
7
+ * It reminds Claude to preserve Ranger Feature Review Specification in the compaction summary.
8
8
  */
9
9
  export async function preCompact(sessionIdOverride) {
10
10
  const sessionId = await getEnabledSessionId(sessionIdOverride);
@@ -19,9 +19,9 @@ export async function preCompact(sessionIdOverride) {
19
19
  }
20
20
  printBlock(`=== RANGER: PRESERVE IN COMPACTION ===
21
21
 
22
- If you created a plan with a **Ranger Feature Specification**, you MUST preserve it in the compaction summary.
22
+ If you created a plan with a **Ranger Feature Review Specification**, you MUST preserve it in the compaction summary.
23
23
 
24
- The specification contains checklist items that will be used with \`ranger feature create\`.`);
24
+ The specification contains scenarios that will be used with \`ranger create\`.`);
25
25
  }
26
26
  catch {
27
27
  // Silently fail - don't interrupt compaction
@@ -1 +1 @@
1
- {"version":3,"file":"preCompact.js","sourceRoot":"","sources":["../../../src/commands/hooks/preCompact.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAChD,OAAO,EAAE,UAAU,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAE9D;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,iBAA0B;IACvD,MAAM,SAAS,GAAG,MAAM,mBAAmB,CAAC,iBAAiB,CAAC,CAAC;IAC/D,IAAI,CAAC,SAAS,EAAE,CAAC;QACb,OAAO;IACX,CAAC;IAED,IAAI,CAAC;QACD,gCAAgC;QAChC,MAAM,KAAK,GAAG,MAAM,QAAQ,EAAE,CAAC;QAC/B,IAAI,CAAC,KAAK,EAAE,CAAC;YACT,OAAO;QACX,CAAC;QAED,UAAU,CAAC;;;;6FAI0E,CAAC,CAAC;IAC3F,CAAC;IAAC,MAAM,CAAC;QACL,6CAA6C;IACjD,CAAC;AACL,CAAC"}
1
+ {"version":3,"file":"preCompact.js","sourceRoot":"","sources":["../../../src/commands/hooks/preCompact.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAChD,OAAO,EAAE,UAAU,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAE9D;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,iBAA0B;IACvD,MAAM,SAAS,GAAG,MAAM,mBAAmB,CAAC,iBAAiB,CAAC,CAAC;IAC/D,IAAI,CAAC,SAAS,EAAE,CAAC;QACb,OAAO;IACX,CAAC;IAED,IAAI,CAAC;QACD,gCAAgC;QAChC,MAAM,KAAK,GAAG,MAAM,QAAQ,EAAE,CAAC;QAC/B,IAAI,CAAC,KAAK,EAAE,CAAC;YACT,OAAO;QACX,CAAC;QAED,UAAU,CAAC;;;;+EAI4D,CAAC,CAAC;IAC7E,CAAC;IAAC,MAAM,CAAC;QACL,6CAA6C;IACjD,CAAC;AACL,CAAC"}
@@ -1,5 +1,6 @@
1
1
  import { appendFile } from 'fs/promises';
2
2
  import { initBranchTracking, shouldAutoEnableAfterClear, autoEnableAfterClear, isSessionEnabled, getCurrentBranch, } from '../utils/sessionCache.js';
3
+ import { createTelemetryCollector } from '../utils/telemetry.js';
3
4
  const RANGER_AUTO_ENABLED_PROMPT = `=================================================================
4
5
  🚨 RANGER IS ACTIVE 🚨
5
6
  =================================================================
@@ -8,13 +9,13 @@ This session has Ranger ENABLED. Before doing ANYTHING else:
8
9
 
9
10
  1. **READ the /ranger skill FIRST** - Run the skill to understand the required workflow for UI features
10
11
 
11
- 2. **Check for existing features** - Run \`ranger feature list\` to see if there's an in-progress feature to resume
12
+ 2. **Check for existing feature reviews** - Run \`ranger list\` to see if there's an in-progress feature review to resume
12
13
 
13
14
  3. **For ANY UI work**: You MUST either:
14
- - Resume an existing feature: \`ranger feature resume <id>\`
15
- - Create a new feature: \`ranger feature create "<name>" -d "<desc>" -c "<checklist item>"\`
15
+ - Resume an existing feature review: \`ranger resume <id>\`
16
+ - Create a new feature review: \`ranger create "<name>" -d "<desc>" -c "<scenario>"\`
16
17
 
17
- 4. **If resuming a feature with reviewer comments**: Run \`ranger feature get-feedback\` to see what reviewers want fixed before making code changes
18
+ 4. **If resuming a feature review with reviewer comments**: Run \`ranger get-review\` to see what reviewers want fixed before making code changes
18
19
 
19
20
  =================================================================`;
20
21
  /**
@@ -60,8 +61,21 @@ export async function sessionStart(sessionIdOverride) {
60
61
  }
61
62
  // Initialize branch tracking - auto-enable session if branch is already enabled
62
63
  initBranchTracking(sessionId);
64
+ const enabled = isSessionEnabled(sessionId);
65
+ // Telemetry: log session start with enabled status
66
+ try {
67
+ const telemetry = createTelemetryCollector('hook:session-start');
68
+ await telemetry.trackCommandStart({
69
+ sessionId,
70
+ hooksEnabled: enabled,
71
+ });
72
+ await telemetry.trackCommandEnd('success');
73
+ }
74
+ catch {
75
+ // Telemetry must never throw
76
+ }
63
77
  // If session is now enabled (via branch or clear), output strong prompting
64
- if (isSessionEnabled(sessionId)) {
78
+ if (enabled) {
65
79
  const branch = getCurrentBranch();
66
80
  const branchInfo = branch && branch !== 'main' && branch !== 'master'
67
81
  ? ` (Branch: ${branch})`
@@ -1 +1 @@
1
- {"version":3,"file":"sessionStart.js","sourceRoot":"","sources":["../../../src/commands/hooks/sessionStart.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EACH,kBAAkB,EAClB,0BAA0B,EAC1B,oBAAoB,EACpB,gBAAgB,EAChB,gBAAgB,GACnB,MAAM,0BAA0B,CAAC;AAElC,MAAM,0BAA0B,GAAG;;;;;;;;;;;;;;;;kEAgB+B,CAAC;AAEnE;;;;;;;GAOG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,iBAA0B;IACzD,IAAI,SAAS,GAAG,iBAAiB,IAAI,EAAE,CAAC;IACxC,IAAI,MAA0B,CAAC;IAE/B,IAAI,CAAC,iBAAiB,EAAE,CAAC;QACrB,4EAA4E;QAC5E,IAAI,KAAK,GAAG,EAAE,CAAC;QACf,IAAI,KAAK,EAAE,MAAM,KAAK,IAAI,OAAO,CAAC,KAAK,EAAE,CAAC;YACtC,KAAK,IAAI,KAAK,CAAC;QACnB,CAAC;QAED,IAAI,CAAC;YACD,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;YAC/B,SAAS,GAAG,IAAI,CAAC,YAAY,CAAC,IAAI,EAAE,CAAC;YACrC,MAAM,GAAG,IAAI,CAAC,QAAQ,CAAC,CAAC;QAC5B,CAAC;QAAC,MAAM,CAAC;YACL,sBAAsB;QAC1B,CAAC;QAED,uEAAuE;QACvE,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC;QAC5C,IAAI,OAAO,IAAI,SAAS,EAAE,CAAC;YACvB,IAAI,CAAC;gBACD,MAAM,UAAU,CACZ,OAAO,EACP,6BAA6B,SAAS,KAAK,CAC9C,CAAC;YACN,CAAC;YAAC,MAAM,CAAC;gBACL,oCAAoC;YACxC,CAAC;QACL,CAAC;IACL,CAAC;IAED,IAAI,SAAS,EAAE,CAAC;QACZ,mFAAmF;QACnF,IAAI,0BAA0B,CAAC,MAAM,CAAC,EAAE,CAAC;YACrC,oBAAoB,CAAC,SAAS,CAAC,CAAC;QACpC,CAAC;QAED,gFAAgF;QAChF,kBAAkB,CAAC,SAAS,CAAC,CAAC;QAE9B,2EAA2E;QAC3E,IAAI,gBAAgB,CAAC,SAAS,CAAC,EAAE,CAAC;YAC9B,MAAM,MAAM,GAAG,gBAAgB,EAAE,CAAC;YAClC,MAAM,UAAU,GACZ,MAAM,IAAI,MAAM,KAAK,MAAM,IAAI,MAAM,KAAK,QAAQ;gBAC9C,CAAC,CAAC,aAAa,MAAM,GAAG;gBACxB,CAAC,CAAC,EAAE,CAAC;YAEb,MAAM,QAAQ,GAAG;gBACb,kBAAkB,EAAE;oBAChB,aAAa,EAAE,cAAc;oBAC7B,iBAAiB,EAAE,0BAA0B,GAAG,UAAU;iBAC7D;aACJ,CAAC;YACF,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC,CAAC;QAC1C,CAAC;IACL,CAAC;AACL,CAAC"}
1
+ {"version":3,"file":"sessionStart.js","sourceRoot":"","sources":["../../../src/commands/hooks/sessionStart.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EACH,kBAAkB,EAClB,0BAA0B,EAC1B,oBAAoB,EACpB,gBAAgB,EAChB,gBAAgB,GACnB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAE,wBAAwB,EAAE,MAAM,uBAAuB,CAAC;AAEjE,MAAM,0BAA0B,GAAG;;;;;;;;;;;;;;;;kEAgB+B,CAAC;AAEnE;;;;;;;GAOG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,iBAA0B;IACzD,IAAI,SAAS,GAAG,iBAAiB,IAAI,EAAE,CAAC;IACxC,IAAI,MAA0B,CAAC;IAE/B,IAAI,CAAC,iBAAiB,EAAE,CAAC;QACrB,4EAA4E;QAC5E,IAAI,KAAK,GAAG,EAAE,CAAC;QACf,IAAI,KAAK,EAAE,MAAM,KAAK,IAAI,OAAO,CAAC,KAAK,EAAE,CAAC;YACtC,KAAK,IAAI,KAAK,CAAC;QACnB,CAAC;QAED,IAAI,CAAC;YACD,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;YAC/B,SAAS,GAAG,IAAI,CAAC,YAAY,CAAC,IAAI,EAAE,CAAC;YACrC,MAAM,GAAG,IAAI,CAAC,QAAQ,CAAC,CAAC;QAC5B,CAAC;QAAC,MAAM,CAAC;YACL,sBAAsB;QAC1B,CAAC;QAED,uEAAuE;QACvE,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC;QAC5C,IAAI,OAAO,IAAI,SAAS,EAAE,CAAC;YACvB,IAAI,CAAC;gBACD,MAAM,UAAU,CACZ,OAAO,EACP,6BAA6B,SAAS,KAAK,CAC9C,CAAC;YACN,CAAC;YAAC,MAAM,CAAC;gBACL,oCAAoC;YACxC,CAAC;QACL,CAAC;IACL,CAAC;IAED,IAAI,SAAS,EAAE,CAAC;QACZ,mFAAmF;QACnF,IAAI,0BAA0B,CAAC,MAAM,CAAC,EAAE,CAAC;YACrC,oBAAoB,CAAC,SAAS,CAAC,CAAC;QACpC,CAAC;QAED,gFAAgF;QAChF,kBAAkB,CAAC,SAAS,CAAC,CAAC;QAE9B,MAAM,OAAO,GAAG,gBAAgB,CAAC,SAAS,CAAC,CAAC;QAE5C,mDAAmD;QACnD,IAAI,CAAC;YACD,MAAM,SAAS,GAAG,wBAAwB,CAAC,oBAAoB,CAAC,CAAC;YACjE,MAAM,SAAS,CAAC,iBAAiB,CAAC;gBAC9B,SAAS;gBACT,YAAY,EAAE,OAAO;aACxB,CAAC,CAAC;YACH,MAAM,SAAS,CAAC,eAAe,CAAC,SAAS,CAAC,CAAC;QAC/C,CAAC;QAAC,MAAM,CAAC;YACL,6BAA6B;QACjC,CAAC;QAED,2EAA2E;QAC3E,IAAI,OAAO,EAAE,CAAC;YACV,MAAM,MAAM,GAAG,gBAAgB,EAAE,CAAC;YAClC,MAAM,UAAU,GACZ,MAAM,IAAI,MAAM,KAAK,MAAM,IAAI,MAAM,KAAK,QAAQ;gBAC9C,CAAC,CAAC,aAAa,MAAM,GAAG;gBACxB,CAAC,CAAC,EAAE,CAAC;YAEb,MAAM,QAAQ,GAAG;gBACb,kBAAkB,EAAE;oBAChB,aAAa,EAAE,cAAc;oBAC7B,iBAAiB,EAAE,0BAA0B,GAAG,UAAU;iBAC7D;aACJ,CAAC;YACF,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC,CAAC;QAC1C,CAAC;IACL,CAAC;AACL,CAAC"}
@@ -1,54 +1,148 @@
1
+ import { open } from 'fs/promises';
1
2
  import { getToken } from '../utils/keychain.js';
2
3
  import { getFeature, concludeSession } from '../utils/featureApi.js';
3
4
  import { getSessionEntry } from '../utils/sessionCache.js';
4
- import { getEnabledSessionId } from './output.js';
5
+ import { getEnabledHookContext } from './output.js';
6
+ import { createTelemetryCollector } from '../utils/telemetry.js';
5
7
  /**
6
8
  * Stop hook handler
7
9
  *
8
- * Only blocks stop for Claude sessions that have registered with a Ranger feature.
9
- * Attempts to conclude the feature session before allowing stop.
10
+ * Only blocks stop for Claude sessions that have registered with a Ranger feature review.
11
+ * Attempts to conclude the feature review session before allowing stop.
10
12
  */
11
13
  export async function stopHook(sessionIdOverride) {
12
- const sessionId = await getEnabledSessionId(sessionIdOverride);
14
+ const context = await getEnabledHookContext(sessionIdOverride);
15
+ const sessionId = context?.sessionId ?? null;
16
+ const stopHookActive = Boolean(context?.input?.stop_hook_active);
17
+ const transcriptPath = typeof context?.input?.transcript_path === 'string'
18
+ ? context.input.transcript_path
19
+ : null;
20
+ let stopAllowed = true;
13
21
  if (!sessionId) {
22
+ await trackStop(sessionId, false, stopAllowed);
14
23
  return;
15
24
  }
16
25
  try {
17
- // Check if this Claude session is registered with a Ranger feature
26
+ // Check if this Claude session is registered with a Ranger feature review
18
27
  const sessionEntry = getSessionEntry(sessionId);
19
28
  if (!sessionEntry) {
20
29
  // Not a Ranger session - allow stop
30
+ await trackStop(sessionId, true, stopAllowed);
21
31
  return;
22
32
  }
33
+ const dashboardUrl = `https://dashboard.ranger.net/features/${sessionEntry.featureId}`;
34
+ const skipToken = 'RANGER_SKIP_VERIFICATION';
23
35
  const token = await getToken();
24
- if (!token) {
25
- // No token configured - allow stop
26
- return;
36
+ const shouldRemind = !stopHookActive;
37
+ let featureName = null;
38
+ let currentSessionId = null;
39
+ const skipRequested = stopHookActive &&
40
+ (await transcriptHasToken(transcriptPath, skipToken));
41
+ const linkIncluded = await transcriptHasToken(transcriptPath, dashboardUrl);
42
+ if (token) {
43
+ try {
44
+ const feature = await getFeature(sessionEntry.featureId);
45
+ featureName = feature.name ?? null;
46
+ currentSessionId = feature.currentSessionId ?? null;
47
+ }
48
+ catch {
49
+ // Fail open for feature lookup
50
+ }
27
51
  }
28
- // Get the feature
29
- const feature = await getFeature(sessionEntry.featureId);
30
- // If there's no current session, allow stop
31
- if (!feature.currentSessionId) {
52
+ if (skipRequested && !linkIncluded) {
53
+ stopAllowed = false;
54
+ const output = {
55
+ decision: 'block',
56
+ reason: `Before ending, include a final message with the feature review link (${dashboardUrl}) and direct the user to visit it. If you are skipping verification, keep \`${skipToken}\` in that final message, then run /exit again.`,
57
+ };
58
+ console.log(JSON.stringify(output));
59
+ await trackStop(sessionId, true, stopAllowed);
32
60
  return;
33
61
  }
34
- // Try to conclude the session
35
- try {
36
- await concludeSession(feature.id, feature.currentSessionId);
37
- return;
62
+ // Try to conclude the session if we have one
63
+ if (token && currentSessionId) {
64
+ try {
65
+ await concludeSession(sessionEntry.featureId, currentSessionId);
66
+ }
67
+ catch (err) {
68
+ if (skipRequested && linkIncluded) {
69
+ await trackStop(sessionId, true, stopAllowed);
70
+ return;
71
+ }
72
+ // Failed to conclude - block with error message
73
+ stopAllowed = false;
74
+ const errorMessage = err instanceof Error ? err.message : String(err);
75
+ const output = {
76
+ decision: 'block',
77
+ reason: `Failed to conclude Ranger feature review session${featureName ? ` for "${featureName}"` : ''}:\n\n${errorMessage}\n\nThis is most likely due to pending scenarios that need to be verified. Please resolve the issue or resume later with:\n ranger resume\n\nIf you are extremely sure this is the user's requirement and want to skip verification for now, send a final message that includes the feature review link (${dashboardUrl}) and the token \`${skipToken}\`, then run /exit again.`,
78
+ };
79
+ console.log(JSON.stringify(output));
80
+ await trackStop(sessionId, true, stopAllowed);
81
+ return;
82
+ }
38
83
  }
39
- catch (err) {
40
- // Failed to conclude - block with error message
41
- const errorMessage = err instanceof Error ? err.message : String(err);
84
+ if (shouldRemind) {
85
+ stopAllowed = false;
42
86
  const output = {
43
87
  decision: 'block',
44
- reason: `Failed to conclude Ranger feature session for "${feature.name}":\n\n${errorMessage}\n\n. This is most likely due to pending checklist items that need to be attempted to be verified. Please resolve the issue or manually conclude with:\n ranger feature conclude-session`,
88
+ reason: `Before ending, include a final message with the feature review link (${dashboardUrl}) and direct the user to visit it.`,
45
89
  };
46
90
  console.log(JSON.stringify(output));
91
+ await trackStop(sessionId, true, stopAllowed);
92
+ return;
47
93
  }
94
+ await trackStop(sessionId, true, stopAllowed);
95
+ return;
48
96
  }
49
97
  catch {
50
98
  // On any error fetching feature, allow stop (fail open)
99
+ await trackStop(sessionId, true, stopAllowed);
51
100
  return;
52
101
  }
53
102
  }
103
+ async function trackStop(sessionId, hooksEnabled, stopAllowed) {
104
+ try {
105
+ const telemetry = createTelemetryCollector('hook:stop');
106
+ await telemetry.trackCommandStart({
107
+ sessionId: sessionId ?? undefined,
108
+ hooksEnabled,
109
+ stopAllowed,
110
+ });
111
+ await telemetry.trackCommandEnd('success');
112
+ }
113
+ catch {
114
+ // Telemetry must never throw
115
+ }
116
+ }
117
+ async function transcriptHasToken(transcriptPath, token) {
118
+ if (!transcriptPath)
119
+ return false;
120
+ const tail = await readTranscriptTail(transcriptPath, 200_000);
121
+ return tail ? tail.includes(token) : false;
122
+ }
123
+ async function readTranscriptTail(transcriptPath, maxBytes) {
124
+ let handle = null;
125
+ try {
126
+ handle = await open(transcriptPath, 'r');
127
+ const stats = await handle.stat();
128
+ const length = Math.min(stats.size, maxBytes);
129
+ if (length <= 0) {
130
+ return '';
131
+ }
132
+ const buffer = Buffer.alloc(length);
133
+ await handle.read(buffer, 0, length, stats.size - length);
134
+ return buffer.toString('utf8');
135
+ }
136
+ catch {
137
+ return null;
138
+ }
139
+ finally {
140
+ try {
141
+ await handle?.close();
142
+ }
143
+ catch {
144
+ // Ignore close errors
145
+ }
146
+ }
147
+ }
54
148
  //# sourceMappingURL=stopHook.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"stopHook.js","sourceRoot":"","sources":["../../../src/commands/hooks/stopHook.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAChD,OAAO,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACrE,OAAO,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAC;AAC3D,OAAO,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAElD;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,QAAQ,CAAC,iBAA0B;IACrD,MAAM,SAAS,GAAG,MAAM,mBAAmB,CAAC,iBAAiB,CAAC,CAAC;IAC/D,IAAI,CAAC,SAAS,EAAE,CAAC;QACb,OAAO;IACX,CAAC;IAED,IAAI,CAAC;QACD,mEAAmE;QACnE,MAAM,YAAY,GAAG,eAAe,CAAC,SAAS,CAAC,CAAC;QAChD,IAAI,CAAC,YAAY,EAAE,CAAC;YAChB,oCAAoC;YACpC,OAAO;QACX,CAAC;QAED,MAAM,KAAK,GAAG,MAAM,QAAQ,EAAE,CAAC;QAC/B,IAAI,CAAC,KAAK,EAAE,CAAC;YACT,mCAAmC;YACnC,OAAO;QACX,CAAC;QAED,kBAAkB;QAClB,MAAM,OAAO,GAAG,MAAM,UAAU,CAAC,YAAY,CAAC,SAAS,CAAC,CAAC;QAEzD,4CAA4C;QAC5C,IAAI,CAAC,OAAO,CAAC,gBAAgB,EAAE,CAAC;YAC5B,OAAO;QACX,CAAC;QAED,8BAA8B;QAC9B,IAAI,CAAC;YACD,MAAM,eAAe,CAAC,OAAO,CAAC,EAAE,EAAE,OAAO,CAAC,gBAAgB,CAAC,CAAC;YAC5D,OAAO;QACX,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACX,gDAAgD;YAChD,MAAM,YAAY,GACd,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YACrD,MAAM,MAAM,GAAG;gBACX,QAAQ,EAAE,OAAO;gBACjB,MAAM,EAAE,kDAAkD,OAAO,CAAC,IAAI,SAAS,YAAY,2LAA2L;aACzR,CAAC;YACF,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC;QACxC,CAAC;IACL,CAAC;IAAC,MAAM,CAAC;QACL,wDAAwD;QACxD,OAAO;IACX,CAAC;AACL,CAAC"}
1
+ {"version":3,"file":"stopHook.js","sourceRoot":"","sources":["../../../src/commands/hooks/stopHook.ts"],"names":[],"mappings":"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"}
@@ -1,13 +1,12 @@
1
1
  export { addEnv } from './addEnv.js';
2
2
  export { clean } from './clean.js';
3
- export { dataMcpServer } from './dataMcpServer.js';
4
3
  export { login } from './login.js';
5
4
  export { start } from './start.js';
6
5
  export { useEnv } from './useEnv.js';
7
6
  export { updateEnv } from './updateEnv.js';
8
- export { verifyInBrowser } from './verifyInBrowser.js';
9
7
  export { update } from './update.js';
10
8
  export { skillup } from './skillup.js';
11
9
  export { envList } from './env.js';
12
10
  export { hook } from './hook.js';
11
+ export { setupCi } from './setupCi.js';
13
12
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/commands/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACnC,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACnC,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACnC,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC3C,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AACvD,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AACvC,OAAO,EAAE,OAAO,EAAE,MAAM,UAAU,CAAC;AACnC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/commands/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACnC,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACnC,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACnC,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC3C,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AACvC,OAAO,EAAE,OAAO,EAAE,MAAM,UAAU,CAAC;AACnC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC"}
@@ -7,9 +7,7 @@ import { getCurrentUser } from './utils/userApi.js';
7
7
  export async function login() {
8
8
  const isInteractive = process.stdin.isTTY && process.stdout.isTTY;
9
9
  if (!isInteractive) {
10
- console.error('Login requires an interactive terminal.');
11
- console.error('In CI, use: ranger start <token> or set RANGER_MCP_TOKEN.');
12
- process.exit(1);
10
+ throw new Error('Login requires an interactive terminal. In CI, use: ranger setup [token] or set RANGER_MCP_TOKEN.');
13
11
  }
14
12
  try {
15
13
  const token = await runDeviceAuthFlow();
@@ -22,8 +20,7 @@ export async function login() {
22
20
  }
23
21
  }
24
22
  catch (error) {
25
- console.error(`\n❌ Login failed: ${error instanceof Error ? error.message : error}`);
26
- process.exit(1);
23
+ throw new Error(`Login failed: ${error instanceof Error ? error.message : error}`);
27
24
  }
28
25
  }
29
26
  //# sourceMappingURL=login.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"login.js","sourceRoot":"","sources":["../../src/commands/login.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAC1D,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAEpD;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,KAAK;IACvB,MAAM,aAAa,GAAG,OAAO,CAAC,KAAK,CAAC,KAAK,IAAI,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC;IAClE,IAAI,CAAC,aAAa,EAAE,CAAC;QACjB,OAAO,CAAC,KAAK,CAAC,2CAA2C,CAAC,CAAC;QAC3D,OAAO,CAAC,KAAK,CACT,2DAA2D,CAC9D,CAAC;QACF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACpB,CAAC;IAED,IAAI,CAAC;QACD,MAAM,KAAK,GAAG,MAAM,iBAAiB,EAAE,CAAC;QAExC,MAAM,MAAM,GAAG,MAAM,cAAc,CAAC,KAAK,CAAC,CAAC;QAC3C,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;YACjB,OAAO,CAAC,GAAG,CAAC,oBAAoB,MAAM,CAAC,IAAI,CAAC,gBAAgB,EAAE,CAAC,CAAC;QACpE,CAAC;aAAM,CAAC;YACJ,OAAO,CAAC,GAAG,CAAC,iCAAiC,CAAC,CAAC;QACnD,CAAC;IACL,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACb,OAAO,CAAC,KAAK,CACT,qBAAqB,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,EAAE,CACxE,CAAC;QACF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACpB,CAAC;AACL,CAAC"}
1
+ {"version":3,"file":"login.js","sourceRoot":"","sources":["../../src/commands/login.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAC1D,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAEpD;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,KAAK;IACvB,MAAM,aAAa,GAAG,OAAO,CAAC,KAAK,CAAC,KAAK,IAAI,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC;IAClE,IAAI,CAAC,aAAa,EAAE,CAAC;QACjB,MAAM,IAAI,KAAK,CACX,mGAAmG,CACtG,CAAC;IACN,CAAC;IAED,IAAI,CAAC;QACD,MAAM,KAAK,GAAG,MAAM,iBAAiB,EAAE,CAAC;QAExC,MAAM,MAAM,GAAG,MAAM,cAAc,CAAC,KAAK,CAAC,CAAC;QAC3C,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;YACjB,OAAO,CAAC,GAAG,CAAC,oBAAoB,MAAM,CAAC,IAAI,CAAC,gBAAgB,EAAE,CAAC,CAAC;QACpE,CAAC;aAAM,CAAC;YACJ,OAAO,CAAC,GAAG,CAAC,iCAAiC,CAAC,CAAC;QACnD,CAAC;IACL,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACb,MAAM,IAAI,KAAK,CACX,iBAAiB,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,EAAE,CACpE,CAAC;IACN,CAAC;AACL,CAAC"}