@ranger-testing/ranger-cli 2.0.5 → 2.0.7

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 (116) hide show
  1. package/build/cli.js +1 -914
  2. package/build/commands/addEnv.js +1 -1
  3. package/build/commands/authEncrypt.js +1 -36
  4. package/build/commands/clean.js +1 -1
  5. package/build/commands/config.js +1 -93
  6. package/build/commands/env.js +1 -98
  7. package/build/commands/feature.js +1 -653
  8. package/build/commands/hook.js +1 -33
  9. package/build/commands/hooks/autoPrompt.js +1 -32
  10. package/build/commands/hooks/disable.js +1 -33
  11. package/build/commands/hooks/enable.js +1 -58
  12. package/build/commands/hooks/exitPlanMode.js +1 -35
  13. package/build/commands/hooks/index.js +1 -12
  14. package/build/commands/hooks/output.js +1 -71
  15. package/build/commands/hooks/planReminder.js +1 -46
  16. package/build/commands/hooks/planStart.js +1 -30
  17. package/build/commands/hooks/postEdit.js +1 -43
  18. package/build/commands/hooks/preCompact.js +1 -30
  19. package/build/commands/hooks/sessionEnd.js +1 -25
  20. package/build/commands/hooks/sessionStart.js +1 -93
  21. package/build/commands/hooks/stopHook.js +1 -155
  22. package/build/commands/index.js +1 -12
  23. package/build/commands/login.js +1 -26
  24. package/build/commands/setupCi.js +1 -189
  25. package/build/commands/skillup.js +1 -80
  26. package/build/commands/start.js +1 -1
  27. package/build/commands/status.js +1 -198
  28. package/build/commands/update.js +1 -182
  29. package/build/commands/updateEnv.js +1 -1
  30. package/build/commands/useEnv.js +1 -1
  31. package/build/commands/utils/activeProfile.js +1 -76
  32. package/build/commands/utils/browserSessionsApi.js +1 -1
  33. package/build/commands/utils/claudeConfig.js +1 -73
  34. package/build/commands/utils/claudePlugin.js +1 -85
  35. package/build/commands/utils/crypto.js +1 -42
  36. package/build/commands/utils/desirePathLog.js +1 -139
  37. package/build/commands/utils/deviceAuth.js +1 -232
  38. package/build/commands/utils/environment.js +1 -65
  39. package/build/commands/utils/featureApi.js +1 -371
  40. package/build/commands/utils/featureReportGenerator.js +1 -204
  41. package/build/commands/utils/fixWebmDuration.js +1 -0
  42. package/build/commands/utils/git.js +1 -44
  43. package/build/commands/utils/keychain.js +1 -1
  44. package/build/commands/utils/localAgentInstallationsApi.js +1 -1
  45. package/build/commands/utils/profileMessages.js +1 -8
  46. package/build/commands/utils/profileSetupBanner.js +1 -167
  47. package/build/commands/utils/rangerRoot.js +1 -60
  48. package/build/commands/utils/reportGenerator.js +1 -130
  49. package/build/commands/utils/retry.js +1 -25
  50. package/build/commands/utils/sessionCache.js +1 -299
  51. package/build/commands/utils/settings.js +1 -313
  52. package/build/commands/utils/skillContent.js +1 -28
  53. package/build/commands/utils/skills.js +1 -1
  54. package/build/commands/utils/telemetry.js +1 -254
  55. package/build/commands/utils/userApi.js +1 -32
  56. package/build/commands/utils/version.js +1 -62
  57. package/build/commands/verifyFeature.js +1 -1343
  58. package/build/commands/verifyInBrowser.js +1 -1
  59. package/package.json +4 -1
  60. package/build/cli.js.map +0 -1
  61. package/build/commands/addEnv.js.map +0 -1
  62. package/build/commands/authEncrypt.js.map +0 -1
  63. package/build/commands/clean.js.map +0 -1
  64. package/build/commands/config.js.map +0 -1
  65. package/build/commands/env.js.map +0 -1
  66. package/build/commands/feature.js.map +0 -1
  67. package/build/commands/hook.js.map +0 -1
  68. package/build/commands/hooks/autoPrompt.js.map +0 -1
  69. package/build/commands/hooks/disable.js.map +0 -1
  70. package/build/commands/hooks/enable.js.map +0 -1
  71. package/build/commands/hooks/exitPlanMode.js.map +0 -1
  72. package/build/commands/hooks/index.js.map +0 -1
  73. package/build/commands/hooks/output.js.map +0 -1
  74. package/build/commands/hooks/planReminder.js.map +0 -1
  75. package/build/commands/hooks/planStart.js.map +0 -1
  76. package/build/commands/hooks/postEdit.js.map +0 -1
  77. package/build/commands/hooks/preCompact.js.map +0 -1
  78. package/build/commands/hooks/sessionEnd.js.map +0 -1
  79. package/build/commands/hooks/sessionStart.js.map +0 -1
  80. package/build/commands/hooks/stopHook.js.map +0 -1
  81. package/build/commands/index.js.map +0 -1
  82. package/build/commands/login.js.map +0 -1
  83. package/build/commands/setupCi.js.map +0 -1
  84. package/build/commands/skillup.js.map +0 -1
  85. package/build/commands/start.js.map +0 -1
  86. package/build/commands/status.js.map +0 -1
  87. package/build/commands/update.js.map +0 -1
  88. package/build/commands/updateEnv.js.map +0 -1
  89. package/build/commands/useEnv.js.map +0 -1
  90. package/build/commands/utils/activeProfile.js.map +0 -1
  91. package/build/commands/utils/browserSessionsApi.js.map +0 -1
  92. package/build/commands/utils/claudeConfig.js.map +0 -1
  93. package/build/commands/utils/claudePlugin.js.map +0 -1
  94. package/build/commands/utils/crypto.js.map +0 -1
  95. package/build/commands/utils/desirePathLog.js.map +0 -1
  96. package/build/commands/utils/deviceAuth.js.map +0 -1
  97. package/build/commands/utils/environment.js.map +0 -1
  98. package/build/commands/utils/featureApi.js.map +0 -1
  99. package/build/commands/utils/featureReportGenerator.js.map +0 -1
  100. package/build/commands/utils/git.js.map +0 -1
  101. package/build/commands/utils/keychain.js.map +0 -1
  102. package/build/commands/utils/localAgentInstallationsApi.js.map +0 -1
  103. package/build/commands/utils/profileMessages.js.map +0 -1
  104. package/build/commands/utils/profileSetupBanner.js.map +0 -1
  105. package/build/commands/utils/rangerRoot.js.map +0 -1
  106. package/build/commands/utils/reportGenerator.js.map +0 -1
  107. package/build/commands/utils/retry.js.map +0 -1
  108. package/build/commands/utils/sessionCache.js.map +0 -1
  109. package/build/commands/utils/settings.js.map +0 -1
  110. package/build/commands/utils/skillContent.js.map +0 -1
  111. package/build/commands/utils/skills.js.map +0 -1
  112. package/build/commands/utils/telemetry.js.map +0 -1
  113. package/build/commands/utils/userApi.js.map +0 -1
  114. package/build/commands/utils/version.js.map +0 -1
  115. package/build/commands/verifyFeature.js.map +0 -1
  116. package/build/commands/verifyInBrowser.js.map +0 -1
@@ -1,155 +1 @@
1
- import { open } from 'fs/promises';
2
- import { getToken } from '../utils/keychain.js';
3
- import { getFeature, concludeSession } from '../utils/featureApi.js';
4
- import { getSessionEntry } from '../utils/sessionCache.js';
5
- import { getEnabledHookContext } from './output.js';
6
- import { createTelemetryCollector } from '../utils/telemetry.js';
7
- /**
8
- * Stop hook handler
9
- *
10
- * Attempts to conclude the feature review session before allowing stop.
11
- * Block conditions are temporarily disabled — the skill prompt now handles
12
- * instructing the agent to share the dashboard link on session end.
13
- */
14
- export async function stopHook(sessionIdOverride) {
15
- const context = await getEnabledHookContext(sessionIdOverride);
16
- const sessionId = context?.sessionId ?? null;
17
- const stopHookActive = Boolean(context?.input?.stop_hook_active);
18
- const transcriptPath = typeof context?.input?.transcript_path === 'string'
19
- ? context.input.transcript_path
20
- : null;
21
- let stopAllowed = true;
22
- if (!sessionId) {
23
- await trackStop(sessionId, false, stopAllowed);
24
- return;
25
- }
26
- try {
27
- // Check if this Claude session is registered with a Ranger feature review
28
- const sessionEntry = getSessionEntry(sessionId);
29
- if (!sessionEntry) {
30
- // Not a Ranger session - allow stop
31
- await trackStop(sessionId, true, stopAllowed);
32
- return;
33
- }
34
- const dashboardUrl = `https://dashboard.ranger.net/features/${sessionEntry.featureId}`;
35
- const skipToken = 'RANGER_SKIP_VERIFICATION';
36
- const token = await getToken();
37
- const shouldRemind = !stopHookActive;
38
- let featureName = null;
39
- let currentSessionId = null;
40
- const skipRequested = stopHookActive &&
41
- (await transcriptHasToken(transcriptPath, skipToken));
42
- const linkIncluded = await transcriptHasToken(transcriptPath, dashboardUrl);
43
- if (token) {
44
- try {
45
- const feature = await getFeature(sessionEntry.featureId);
46
- featureName = feature.name ?? null;
47
- currentSessionId = feature.currentSessionId ?? null;
48
- }
49
- catch {
50
- // Fail open for feature lookup
51
- }
52
- }
53
- // --- Block conditions temporarily disabled (handled by skill prompt instead) ---
54
- // if (skipRequested && !linkIncluded) {
55
- // stopAllowed = false;
56
- // const output = {
57
- // decision: 'block',
58
- // 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.`,
59
- // };
60
- // console.log(JSON.stringify(output));
61
- // await trackStop(sessionId, true, stopAllowed);
62
- // return;
63
- // }
64
- // Try to conclude the session if we have one
65
- if (token && currentSessionId) {
66
- try {
67
- await concludeSession(sessionEntry.featureId, currentSessionId);
68
- }
69
- catch (err) {
70
- // if (skipRequested && linkIncluded) {
71
- // await trackStop(sessionId, true, stopAllowed);
72
- // return;
73
- // }
74
- if (skipRequested) {
75
- await trackStop(sessionId, true, stopAllowed);
76
- return;
77
- }
78
- // Failed to conclude - block with error message
79
- stopAllowed = false;
80
- const errorMessage = err instanceof Error ? err.message : String(err);
81
- const output = {
82
- decision: 'block',
83
- 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.`,
84
- };
85
- console.log(JSON.stringify(output));
86
- await trackStop(sessionId, true, stopAllowed);
87
- return;
88
- }
89
- }
90
- // if (shouldRemind && !linkIncluded) {
91
- // stopAllowed = false;
92
- // const output = {
93
- // decision: 'block',
94
- // reason: `Before ending, include a final message with the feature review link (${dashboardUrl}) and direct the user to visit it.`,
95
- // };
96
- // console.log(JSON.stringify(output));
97
- // await trackStop(sessionId, true, stopAllowed);
98
- // return;
99
- // }
100
- // --- End disabled block conditions ---
101
- await trackStop(sessionId, true, stopAllowed);
102
- return;
103
- }
104
- catch {
105
- // On any error fetching feature, allow stop (fail open)
106
- await trackStop(sessionId, true, stopAllowed);
107
- return;
108
- }
109
- }
110
- async function trackStop(sessionId, hooksEnabled, stopAllowed) {
111
- try {
112
- const telemetry = createTelemetryCollector('hook:stop');
113
- await telemetry.trackCommandStart({
114
- sessionId: sessionId ?? undefined,
115
- hooksEnabled,
116
- stopAllowed,
117
- });
118
- await telemetry.trackCommandEnd('success');
119
- }
120
- catch {
121
- // Telemetry must never throw
122
- }
123
- }
124
- async function transcriptHasToken(transcriptPath, token) {
125
- if (!transcriptPath)
126
- return false;
127
- const tail = await readTranscriptTail(transcriptPath, 200_000);
128
- return tail ? tail.includes(token) : false;
129
- }
130
- async function readTranscriptTail(transcriptPath, maxBytes) {
131
- let handle = null;
132
- try {
133
- handle = await open(transcriptPath, 'r');
134
- const stats = await handle.stat();
135
- const length = Math.min(stats.size, maxBytes);
136
- if (length <= 0) {
137
- return '';
138
- }
139
- const buffer = Buffer.alloc(length);
140
- await handle.read(buffer, 0, length, stats.size - length);
141
- return buffer.toString('utf8');
142
- }
143
- catch {
144
- return null;
145
- }
146
- finally {
147
- try {
148
- await handle?.close();
149
- }
150
- catch {
151
- // Ignore close errors
152
- }
153
- }
154
- }
155
- //# sourceMappingURL=stopHook.js.map
1
+ (function(_0x3f6a23,_0x4073c5){const _0x4c16a1=_0x157a,_0x265228=_0x3f6a23();while(!![]){try{const _0x3ca867=parseInt(_0x4c16a1(0x122))/0x1*(-parseInt(_0x4c16a1(0x132))/0x2)+-parseInt(_0x4c16a1(0x120))/0x3+parseInt(_0x4c16a1(0x129))/0x4*(-parseInt(_0x4c16a1(0x131))/0x5)+parseInt(_0x4c16a1(0x130))/0x6+-parseInt(_0x4c16a1(0x126))/0x7*(-parseInt(_0x4c16a1(0x118))/0x8)+parseInt(_0x4c16a1(0x123))/0x9+parseInt(_0x4c16a1(0x11e))/0xa;if(_0x3ca867===_0x4073c5)break;else _0x265228['push'](_0x265228['shift']());}catch(_0x1388ea){_0x265228['push'](_0x265228['shift']());}}}(_0x40ee,0x73e3e));import{open}from'fs/promises';import{getToken}from'../utils/keychain.js';import{getFeature,concludeSession}from'../utils/featureApi.js';import{getSessionEntry}from'../utils/sessionCache.js';import{getEnabledHookContext}from'./output.js';function _0x157a(_0x2012da,_0x344bf3){_0x2012da=_0x2012da-0x117;const _0x40ee9a=_0x40ee();let _0x157a90=_0x40ee9a[_0x2012da];return _0x157a90;}import{createTelemetryCollector}from'../utils/telemetry.js';export async function stopHook(_0x24376b){const _0x3251dc=_0x157a,_0x1dd9c7={'wgAeZ':function(_0x2b3b0a,_0x27234d){return _0x2b3b0a(_0x27234d);},'KMdIP':function(_0x5d08e4,_0x3cb32a,_0x2de31d,_0x18ec8f){return _0x5d08e4(_0x3cb32a,_0x2de31d,_0x18ec8f);},'HcyiA':function(_0x584050,_0x1834be,_0x354e5b){return _0x584050(_0x1834be,_0x354e5b);},'ePKvS':function(_0xe8bb0f,_0x54f38e){return _0xe8bb0f(_0x54f38e);},'rUZhW':'block'},_0x5c5ab8=await _0x1dd9c7['wgAeZ'](getEnabledHookContext,_0x24376b),_0x3e5498=_0x5c5ab8?.['sessionId']??null,_0x2df8ba=Boolean(_0x5c5ab8?.[_0x3251dc(0x135)]?.['stop_hook_active']),_0x23fe7b=typeof _0x5c5ab8?.[_0x3251dc(0x135)]?.['transcript_path']==='string'?_0x5c5ab8[_0x3251dc(0x135)][_0x3251dc(0x11c)]:null;let _0x3e3a77=!![];if(!_0x3e5498){await _0x1dd9c7[_0x3251dc(0x12e)](trackStop,_0x3e5498,![],_0x3e3a77);return;}try{const _0x45019f=_0x1dd9c7[_0x3251dc(0x121)](getSessionEntry,_0x3e5498);if(!_0x45019f){await _0x1dd9c7[_0x3251dc(0x12e)](trackStop,_0x3e5498,!![],_0x3e3a77);return;}const _0x24b6ca=_0x3251dc(0x117)+_0x45019f['featureId'],_0x5d5355=_0x3251dc(0x13a),_0x3536bd=await getToken(),_0x29c09c=!_0x2df8ba;let _0x3ef77e=null,_0x1968d9=null;const _0x258b65=_0x2df8ba&&await transcriptHasToken(_0x23fe7b,_0x5d5355),_0x54674f=await _0x1dd9c7[_0x3251dc(0x125)](transcriptHasToken,_0x23fe7b,_0x24b6ca);if(_0x3536bd)try{const _0x5346a5=await getFeature(_0x45019f['featureId']);_0x3ef77e=_0x5346a5['name']??null,_0x1968d9=_0x5346a5[_0x3251dc(0x133)]??null;}catch{}if(_0x3536bd&&_0x1968d9)try{await concludeSession(_0x45019f[_0x3251dc(0x11a)],_0x1968d9);}catch(_0x4d0fcb){if(_0x258b65){await trackStop(_0x3e5498,!![],_0x3e3a77);return;}_0x3e3a77=![];const _0x301b20=_0x4d0fcb instanceof Error?_0x4d0fcb['message']:_0x1dd9c7[_0x3251dc(0x137)](String,_0x4d0fcb),_0x1a4773={'decision':_0x1dd9c7['rUZhW'],'reason':'Failed\x20to\x20conclude\x20Ranger\x20feature\x20review\x20session'+(_0x3ef77e?_0x3251dc(0x138)+_0x3ef77e+'\x22':'')+_0x3251dc(0x139)+_0x301b20+'\x0a\x0aThis\x20is\x20most\x20likely\x20due\x20to\x20pending\x20scenarios\x20that\x20need\x20to\x20be\x20verified.\x20Please\x20resolve\x20the\x20issue\x20or\x20resume\x20later\x20with:\x0a\x20\x20ranger\x20resume\x0a\x0aIf\x20you\x20are\x20extremely\x20sure\x20this\x20is\x20the\x20user\x27s\x20requirement\x20and\x20want\x20to\x20skip\x20verification\x20for\x20now,\x20send\x20a\x20final\x20message\x20that\x20includes\x20the\x20feature\x20review\x20link\x20('+_0x24b6ca+_0x3251dc(0x12f)+_0x5d5355+'`,\x20then\x20run\x20/exit\x20again.'};console['log'](JSON[_0x3251dc(0x127)](_0x1a4773)),await trackStop(_0x3e5498,!![],_0x3e3a77);return;}await trackStop(_0x3e5498,!![],_0x3e3a77);return;}catch{await trackStop(_0x3e5498,!![],_0x3e3a77);return;}}function _0x40ee(){const _0x3d59b4=['stringify','alloc','3412SjRXAh','includes','SytBH','toString','trackCommandEnd','KMdIP',')\x20and\x20the\x20token\x20`','2576640JGFxqw','3475BSWwfZ','274svHPhN','currentSessionId','read','input','gxPMz','ePKvS','\x20for\x20\x22',':\x0a\x0a','RANGER_SKIP_VERIFICATION','https://dashboard.ranger.net/features/','5324992QofYoV','trackCommandStart','featureId','OfgTA','transcript_path','success','1363480idPyFb','size','172089nEfXYP','wgAeZ','3727CGElEG','3636639gywTUB','close','HcyiA','7zaBCxp'];_0x40ee=function(){return _0x3d59b4;};return _0x40ee();}async function trackStop(_0x24a04e,_0x3bff4a,_0x438664){const _0x20c7ea=_0x157a,_0x14f254={'byreI':function(_0x19c399,_0x431d43){return _0x19c399??_0x431d43;}};try{const _0xe6d7dd=createTelemetryCollector('hook:stop');await _0xe6d7dd[_0x20c7ea(0x119)]({'sessionId':_0x14f254['byreI'](_0x24a04e,undefined),'hooksEnabled':_0x3bff4a,'stopAllowed':_0x438664}),await _0xe6d7dd[_0x20c7ea(0x12d)](_0x20c7ea(0x11d));}catch{}}async function transcriptHasToken(_0x159bde,_0x5d9c43){const _0x2777bd=_0x157a,_0x31df38={'OfgTA':function(_0x130b61,_0x132182,_0xca8d16){return _0x130b61(_0x132182,_0xca8d16);}};if(!_0x159bde)return![];const _0x1a6f11=await _0x31df38[_0x2777bd(0x11b)](readTranscriptTail,_0x159bde,0x30d40);return _0x1a6f11?_0x1a6f11[_0x2777bd(0x12a)](_0x5d9c43):![];}async function readTranscriptTail(_0x4293ae,_0x166ace){const _0x168674=_0x157a,_0x5eb5fa={'SytBH':function(_0x2481a5,_0x232a5e,_0xb20a9){return _0x2481a5(_0x232a5e,_0xb20a9);},'gxPMz':function(_0x1f9e37,_0x43e3dd){return _0x1f9e37<=_0x43e3dd;}};let _0x2b1fbc=null;try{_0x2b1fbc=await _0x5eb5fa[_0x168674(0x12b)](open,_0x4293ae,'r');const _0x4ff503=await _0x2b1fbc['stat'](),_0x4d35ab=Math['min'](_0x4ff503['size'],_0x166ace);if(_0x5eb5fa[_0x168674(0x136)](_0x4d35ab,0x0))return'';const _0x441109=Buffer[_0x168674(0x128)](_0x4d35ab);return await _0x2b1fbc[_0x168674(0x134)](_0x441109,0x0,_0x4d35ab,_0x4ff503[_0x168674(0x11f)]-_0x4d35ab),_0x441109[_0x168674(0x12c)]('utf8');}catch{return null;}finally{try{await _0x2b1fbc?.[_0x168674(0x124)]();}catch{}}}
@@ -1,12 +1 @@
1
- export { addEnv } from './addEnv.js';
2
- export { clean } from './clean.js';
3
- export { login } from './login.js';
4
- export { start } from './start.js';
5
- export { useEnv } from './useEnv.js';
6
- export { updateEnv } from './updateEnv.js';
7
- export { update } from './update.js';
8
- export { skillup } from './skillup.js';
9
- export { envList } from './env.js';
10
- export { hook } from './hook.js';
11
- export { setupCi } from './setupCi.js';
12
- //# sourceMappingURL=index.js.map
1
+ (function(_0x1446e6,_0x1ef1c7){var _0x234851=_0x4d9e,_0x4784ef=_0x1446e6();while(!![]){try{var _0x268d56=-parseInt(_0x234851(0x1d6))/0x1+parseInt(_0x234851(0x1d2))/0x2+-parseInt(_0x234851(0x1d4))/0x3+-parseInt(_0x234851(0x1d5))/0x4+-parseInt(_0x234851(0x1d8))/0x5+-parseInt(_0x234851(0x1d1))/0x6*(-parseInt(_0x234851(0x1d3))/0x7)+parseInt(_0x234851(0x1d7))/0x8;if(_0x268d56===_0x1ef1c7)break;else _0x4784ef['push'](_0x4784ef['shift']());}catch(_0x4db655){_0x4784ef['push'](_0x4784ef['shift']());}}}(_0x491e,0xd6743));export{addEnv}from'./addEnv.js';export{clean}from'./clean.js';export{login}from'./login.js';export{start}from'./start.js';export{useEnv}from'./useEnv.js';function _0x4d9e(_0xc65bbd,_0x5c8f67){_0xc65bbd=_0xc65bbd-0x1d1;var _0x491ea1=_0x491e();var _0x4d9e7c=_0x491ea1[_0xc65bbd];return _0x4d9e7c;}export{updateEnv}from'./updateEnv.js';function _0x491e(){var _0x27b270=['26567888MSnZfK','3914050NkXuNS','94920CVMGzq','3398966KSODys','119vYJjcM','1776126esuXUm','5656584EjMCLW','1622008qZYfKb'];_0x491e=function(){return _0x27b270;};return _0x491e();}export{update}from'./update.js';export{skillup}from'./skillup.js';export{envList}from'./env.js';export{hook}from'./hook.js';export{setupCi}from'./setupCi.js';
@@ -1,26 +1 @@
1
- import { runDeviceAuthFlow } from './utils/deviceAuth.js';
2
- import { getCurrentUser } from './utils/userApi.js';
3
- /**
4
- * Standalone login command — runs device auth + key provisioning
5
- * without the full `start` setup (Chromium, plugins, etc.).
6
- */
7
- export async function login() {
8
- const isInteractive = process.stdin.isTTY && process.stdout.isTTY;
9
- if (!isInteractive) {
10
- throw new Error('Login requires an interactive terminal. In CI, use: ranger setup [token] or set RANGER_CLI_TOKEN.');
11
- }
12
- try {
13
- const token = await runDeviceAuthFlow();
14
- const result = await getCurrentUser(token);
15
- if (result.success) {
16
- console.log(`\n✅ Logged in to ${result.user.organizationName}`);
17
- }
18
- else {
19
- console.log('\n✅ API key stored successfully');
20
- }
21
- }
22
- catch (error) {
23
- throw new Error(`Login failed: ${error instanceof Error ? error.message : error}`);
24
- }
25
- }
26
- //# sourceMappingURL=login.js.map
1
+ function _0x3da4(){const _0x1eab73=['\x0a✅\x20API\x20key\x20stored\x20successfully','success','485804AJScAn','592239OdtlYY','bkmet','2384816xPegUJ','Login\x20failed:\x20','3907075OLhOKU','stdin','isTTY','\x0a✅\x20Logged\x20in\x20to\x20','4942800uNuWKN','2uJdkjt','72rJXuov','1924239CUtNfc','log','user','294732sbsloF'];_0x3da4=function(){return _0x1eab73;};return _0x3da4();}function _0x1e82(_0x2b4fbf,_0x2e559e){_0x2b4fbf=_0x2b4fbf-0x1bc;const _0x3da438=_0x3da4();let _0x1e822d=_0x3da438[_0x2b4fbf];return _0x1e822d;}(function(_0x194849,_0x493c73){const _0x4354be=_0x1e82,_0x36495d=_0x194849();while(!![]){try{const _0x52bd4d=parseInt(_0x4354be(0x1bc))/0x1+parseInt(_0x4354be(0x1c5))/0x2*(parseInt(_0x4354be(0x1c7))/0x3)+-parseInt(_0x4354be(0x1cd))/0x4+parseInt(_0x4354be(0x1c0))/0x5+-parseInt(_0x4354be(0x1c4))/0x6+-parseInt(_0x4354be(0x1be))/0x7+-parseInt(_0x4354be(0x1c6))/0x8*(parseInt(_0x4354be(0x1ca))/0x9);if(_0x52bd4d===_0x493c73)break;else _0x36495d['push'](_0x36495d['shift']());}catch(_0x4738a1){_0x36495d['push'](_0x36495d['shift']());}}}(_0x3da4,0x6a0dc));import{runDeviceAuthFlow}from'./utils/deviceAuth.js';import{getCurrentUser}from'./utils/userApi.js';export async function login(){const _0x45fe64=_0x1e82,_0x41db5f={'bkmet':'Login\x20requires\x20an\x20interactive\x20terminal.\x20In\x20CI,\x20use:\x20ranger\x20setup\x20[token]\x20or\x20set\x20RANGER_CLI_TOKEN.'},_0x5e9986=process[_0x45fe64(0x1c1)]['isTTY']&&process['stdout'][_0x45fe64(0x1c2)];if(!_0x5e9986)throw new Error(_0x41db5f[_0x45fe64(0x1bd)]);try{const _0x1b4855=await runDeviceAuthFlow(),_0x390a30=await getCurrentUser(_0x1b4855);_0x390a30[_0x45fe64(0x1cc)]?console[_0x45fe64(0x1c8)](_0x45fe64(0x1c3)+_0x390a30[_0x45fe64(0x1c9)]['organizationName']):console[_0x45fe64(0x1c8)](_0x45fe64(0x1cb));}catch(_0x443026){throw new Error(_0x45fe64(0x1bf)+(_0x443026 instanceof Error?_0x443026['message']:_0x443026));}}
@@ -1,189 +1 @@
1
- import { mkdir, readFile, readdir } from 'fs/promises';
2
- import { join } from 'path';
3
- import { existsSync } from 'fs';
4
- import { authenticate, ensureRangerDir, ensureChromium, writeRangerGitignore, } from './start.js';
5
- import { skillup } from './skillup.js';
6
- import { getRangerDir } from './utils/rangerRoot.js';
7
- import { writeActiveProfileName } from './utils/activeProfile.js';
8
- import { saveSettings } from './utils/settings.js';
9
- import { decrypt } from './utils/crypto.js';
10
- import { getToken } from './utils/keychain.js';
11
- import { runClaudeCommand, isMarketplaceAdded, isPluginInstalled, } from './utils/claudePlugin.js';
12
- /**
13
- * Find a CI profile to activate.
14
- * If profileName is specified, use it. Otherwise auto-detect from .ranger/ci/.
15
- */
16
- async function findCiProfile(profileName) {
17
- const rangerDir = getRangerDir();
18
- const ciDir = join(rangerDir, 'ci');
19
- if (profileName) {
20
- const profilePath = join(ciDir, profileName);
21
- // Profile may not exist yet if --base-url will create it
22
- return { name: profileName, path: profilePath };
23
- }
24
- // Auto-detect: scan .ranger/ci/ for directories
25
- if (!existsSync(ciDir)) {
26
- throw new Error('No CI profiles found. Create one first with: ranger profile add <name> --ci\n' +
27
- 'Or specify a profile name with --profile and --base-url to create one.');
28
- }
29
- const entries = await readdir(ciDir, { withFileTypes: true });
30
- const profiles = entries.filter((e) => e.isDirectory()).map((e) => e.name);
31
- if (profiles.length === 0) {
32
- throw new Error('No CI profiles found in .ranger/ci/. Create one first with: ranger profile add <name> --ci\n' +
33
- 'Or specify a profile name with --profile and --base-url to create one.');
34
- }
35
- if (profiles.length === 1) {
36
- const name = profiles[0];
37
- console.log(`Auto-detected CI profile: ${name}`);
38
- return { name, path: join(ciDir, name) };
39
- }
40
- // Multiple profiles — require --profile flag
41
- throw new Error(`Multiple CI profiles found: ${profiles.join(', ')}. Use --profile to specify which one.`);
42
- }
43
- /**
44
- * Install Claude Code plugin at project scope (non-interactive).
45
- */
46
- async function installPluginNonInteractive() {
47
- const alreadyInstalled = await isPluginInstalled('ranger@trailhead');
48
- if (alreadyInstalled) {
49
- console.log('✓ Claude Code plugin already installed');
50
- return false;
51
- }
52
- console.log('Installing Claude Code plugin (project level)...');
53
- const marketplaceAlreadyAdded = await isMarketplaceAdded('trailhead');
54
- let marketplaceReady = marketplaceAlreadyAdded;
55
- if (marketplaceAlreadyAdded) {
56
- console.log('✓ Marketplace already added');
57
- }
58
- else {
59
- const result = await runClaudeCommand([
60
- 'plugin',
61
- 'marketplace',
62
- 'add',
63
- 'ranger-testing/trailhead',
64
- ]);
65
- if (!result.success) {
66
- console.error('Failed to add marketplace:', result.error);
67
- console.log('You can install manually: claude plugin marketplace add ranger-testing/trailhead');
68
- }
69
- else {
70
- marketplaceReady = true;
71
- }
72
- }
73
- if (marketplaceReady) {
74
- const result = await runClaudeCommand([
75
- 'plugin',
76
- 'install',
77
- 'ranger@trailhead',
78
- '--scope',
79
- 'project',
80
- ]);
81
- if (!result.success) {
82
- console.error('Failed to install plugin:', result.error);
83
- console.log('You can install manually: claude plugin install ranger@trailhead --scope project');
84
- }
85
- else {
86
- console.log('✓ Claude Code plugin installed');
87
- }
88
- }
89
- return true;
90
- }
91
- /**
92
- * Non-interactive CI setup. Authenticates, installs Chromium, activates a CI profile,
93
- * installs plugin and skills — all without prompts.
94
- */
95
- export async function setupCi(token, options, telemetry) {
96
- console.log('\n🔧 Ranger CI Setup\n');
97
- // Phase 1: Auth
98
- telemetry?.trackPhaseStart('auth');
99
- await authenticate(token);
100
- telemetry?.trackPhaseEnd('auth');
101
- // Phase 2: .ranger/ directory
102
- telemetry?.trackPhaseStart('dir_setup');
103
- const { path: rangerDir, installed: dirCreated } = await ensureRangerDir();
104
- await writeRangerGitignore(rangerDir);
105
- // Ensure sessions directory exists
106
- const sessionsDir = join(rangerDir, 'sessions');
107
- if (!existsSync(sessionsDir)) {
108
- await mkdir(sessionsDir, { recursive: true });
109
- }
110
- telemetry?.trackPhaseEnd('dir_setup', { installed: dirCreated });
111
- // Phase 3: Chromium
112
- telemetry?.trackPhaseStart('chromium');
113
- let chromiumInstalled = false;
114
- if (options?.skipChromium) {
115
- console.log('✓ Skipping Chromium check (--skip-chromium)');
116
- }
117
- else {
118
- chromiumInstalled = await ensureChromium();
119
- }
120
- telemetry?.trackPhaseEnd('chromium', {
121
- installed: chromiumInstalled,
122
- skipped: !!options?.skipChromium,
123
- });
124
- // Phase 4: Profile activation
125
- telemetry?.trackPhaseStart('profile_activate');
126
- const profile = await findCiProfile(options?.profile);
127
- // Create/update settings if --base-url provided
128
- let createdSettings = false;
129
- if (options?.baseUrl) {
130
- await mkdir(profile.path, { recursive: true });
131
- await saveSettings(profile.name, {
132
- baseUrl: options.baseUrl,
133
- headless: true,
134
- });
135
- console.log(`✓ Created profile settings: baseUrl=${options.baseUrl}`);
136
- createdSettings = true;
137
- }
138
- // Verify profile has settings
139
- const settingsPath = join(profile.path, 'settings.json');
140
- if (!existsSync(settingsPath) && !createdSettings) {
141
- throw new Error(`CI profile "${profile.name}" has no settings.json. Use --base-url to configure it.`);
142
- }
143
- // Check auth state
144
- const authPath = join(profile.path, 'auth.json');
145
- const encryptedAuthPath = join(profile.path, 'auth.json.enc');
146
- const hasAuth = existsSync(authPath);
147
- const hasEncryptedAuth = existsSync(encryptedAuthPath);
148
- if (hasEncryptedAuth) {
149
- // Verify we can decrypt it
150
- try {
151
- const apiToken = await getToken();
152
- if (!apiToken) {
153
- throw new Error('No API token available for decryption');
154
- }
155
- const encrypted = await readFile(encryptedAuthPath);
156
- decrypt(encrypted, apiToken);
157
- console.log('✓ Encrypted auth verified (will decrypt at runtime)');
158
- }
159
- catch (error) {
160
- const msg = error instanceof Error ? error.message : String(error);
161
- throw new Error(`Failed to verify encrypted auth for profile "${profile.name}": ${msg}`);
162
- }
163
- }
164
- else if (hasAuth) {
165
- console.log('✓ Auth state found');
166
- }
167
- else {
168
- console.log(' No auth state found (app may not require authentication)');
169
- }
170
- // Set as active profile
171
- await writeActiveProfileName(profile.name);
172
- console.log(`✓ Active profile: ${profile.name}`);
173
- telemetry?.trackPhaseEnd('profile_activate', {
174
- profileName: profile.name,
175
- hasAuth,
176
- hasEncryptedAuth,
177
- createdSettings,
178
- });
179
- // Phase 5: Plugin
180
- telemetry?.trackPhaseStart('plugin');
181
- const pluginInstalled = await installPluginNonInteractive();
182
- telemetry?.trackPhaseEnd('plugin', { installed: pluginInstalled });
183
- // Phase 6: Skills
184
- telemetry?.trackPhaseStart('skills');
185
- await skillup({ autoInstall: 'project' });
186
- telemetry?.trackPhaseEnd('skills');
187
- console.log('\n✅ Ranger CI setup complete!\n');
188
- }
189
- //# sourceMappingURL=setupCi.js.map
1
+ (function(_0x11baca,_0x49a749){const _0x15315c=_0x48b8,_0x1445ed=_0x11baca();while(!![]){try{const _0x9d37d0=-parseInt(_0x15315c(0x18f))/0x1+-parseInt(_0x15315c(0x195))/0x2+parseInt(_0x15315c(0x1a0))/0x3*(-parseInt(_0x15315c(0x191))/0x4)+parseInt(_0x15315c(0x1a4))/0x5*(parseInt(_0x15315c(0x178))/0x6)+parseInt(_0x15315c(0x17a))/0x7+-parseInt(_0x15315c(0x190))/0x8+parseInt(_0x15315c(0x18b))/0x9;if(_0x9d37d0===_0x49a749)break;else _0x1445ed['push'](_0x1445ed['shift']());}catch(_0x20c1ec){_0x1445ed['push'](_0x1445ed['shift']());}}}(_0x38ec,0xd210b));import{mkdir,readFile,readdir}from'fs/promises';import{join}from'path';import{existsSync}from'fs';import{authenticate,ensureRangerDir,ensureChromium,writeRangerGitignore}from'./start.js';import{skillup}from'./skillup.js';function _0x38ec(){const _0x4e151a=['install','\x20\x20No\x20auth\x20state\x20found\x20(app\x20may\x20not\x20require\x20authentication)','HsKmO','isDirectory','name','add','JbAhi','You\x20can\x20install\x20manually:\x20claude\x20plugin\x20marketplace\x20add\x20ranger-testing/trailhead','plugin','project','Auto-detected\x20CI\x20profile:\x20','6126HMBaTc','settings.json','11201862LmWabT','profile','baseUrl','CnXmE','trackPhaseStart','fTVxg','✓\x20Skipping\x20Chromium\x20check\x20(--skip-chromium)','✓\x20Claude\x20Code\x20plugin\x20already\x20installed','Or\x20specify\x20a\x20profile\x20name\x20with\x20--profile\x20and\x20--base-url\x20to\x20create\x20one.','ApoCl','trackPhaseEnd','auth.json','success','TrJbl','XCDAS','chromium','\x0a🔧\x20Ranger\x20CI\x20Setup\x0a','27275229UIsBJx','auth','error','✓\x20Auth\x20state\x20found','1535969KWxItf','1197624BESdIL','2709444oumnWz','xQzBn','AMiCk','CI\x20profile\x20\x22','1948090uCcwNB','filter','Qmxxt','log','ARjsM','✓\x20Encrypted\x20auth\x20verified\x20(will\x20decrypt\x20at\x20runtime)','dir_setup','length','ndTDq','message','No\x20API\x20token\x20available\x20for\x20decryption','6xahcoq','mRSTH','KkyfL','JLtVP','1195AoIAWF','ranger@trailhead','✓\x20Claude\x20Code\x20plugin\x20installed','skipChromium','Installing\x20Claude\x20Code\x20plugin\x20(project\x20level)...','QmEqH','ranger-testing/trailhead','profile_activate','MTxvb','snixi','uTZQh'];_0x38ec=function(){return _0x4e151a;};return _0x38ec();}import{getRangerDir}from'./utils/rangerRoot.js';import{writeActiveProfileName}from'./utils/activeProfile.js';function _0x48b8(_0x48f812,_0x5d5370){_0x48f812=_0x48f812-0x163;const _0x38ec44=_0x38ec();let _0x48b816=_0x38ec44[_0x48f812];return _0x48b816;}import{saveSettings}from'./utils/settings.js';import{decrypt}from'./utils/crypto.js';import{getToken}from'./utils/keychain.js';import{runClaudeCommand,isMarketplaceAdded,isPluginInstalled}from'./utils/claudePlugin.js';async function findCiProfile(_0x31ccb7){const _0x3491f7=_0x48b8,_0x52fefb={'bGiVn':function(_0x434054,_0x5a7a56,_0x23aba0){return _0x434054(_0x5a7a56,_0x23aba0);},'ASluF':function(_0x361d2b,_0x320486){return _0x361d2b===_0x320486;},'HHoPs':function(_0x5133cd,_0x1172d4){return _0x5133cd+_0x1172d4;},'snixi':'No\x20CI\x20profiles\x20found\x20in\x20.ranger/ci/.\x20Create\x20one\x20first\x20with:\x20ranger\x20profile\x20add\x20<name>\x20--ci\x0a','JbAhi':function(_0x2ea502,_0x3b0133){return _0x2ea502===_0x3b0133;}},_0x470f90=getRangerDir(),_0x5caa28=_0x52fefb['bGiVn'](join,_0x470f90,'ci');if(_0x31ccb7){const _0x13d3de=join(_0x5caa28,_0x31ccb7);return{'name':_0x31ccb7,'path':_0x13d3de};}if(!existsSync(_0x5caa28))throw new Error('No\x20CI\x20profiles\x20found.\x20Create\x20one\x20first\x20with:\x20ranger\x20profile\x20add\x20<name>\x20--ci\x0a'+_0x3491f7(0x182));const _0x3c0f6f=await readdir(_0x5caa28,{'withFileTypes':!![]}),_0x20d7f2=_0x3c0f6f[_0x3491f7(0x196)](_0x15f4e7=>_0x15f4e7[_0x3491f7(0x170)]())['map'](_0x5ade18=>_0x5ade18['name']);if(_0x52fefb['ASluF'](_0x20d7f2['length'],0x0))throw new Error(_0x52fefb['HHoPs'](_0x52fefb[_0x3491f7(0x16b)],_0x3491f7(0x182)));if(_0x52fefb[_0x3491f7(0x173)](_0x20d7f2[_0x3491f7(0x19c)],0x1)){const _0x42824c=_0x20d7f2[0x0];return console['log'](_0x3491f7(0x177)+_0x42824c),{'name':_0x42824c,'path':_0x52fefb['bGiVn'](join,_0x5caa28,_0x42824c)};}throw new Error('Multiple\x20CI\x20profiles\x20found:\x20'+_0x20d7f2['join'](',\x20')+'.\x20Use\x20--profile\x20to\x20specify\x20which\x20one.');}async function installPluginNonInteractive(){const _0x2ebfe5=_0x48b8,_0x2a824f={'lmQSB':'ranger@trailhead','fTVxg':_0x2ebfe5(0x181),'ARjsM':function(_0x3da53d,_0x29e12e){return _0x3da53d(_0x29e12e);},'KkyfL':'plugin','uTZQh':_0x2ebfe5(0x172),'dRzIU':_0x2ebfe5(0x168),'OGZWu':function(_0x47eac9,_0x3941c9){return _0x47eac9(_0x3941c9);},'ThNlq':_0x2ebfe5(0x16d),'DOTSw':'Failed\x20to\x20install\x20plugin:','GRrVt':_0x2ebfe5(0x164)},_0x51f9c1=await isPluginInstalled(_0x2a824f['lmQSB']);if(_0x51f9c1)return console[_0x2ebfe5(0x198)](_0x2a824f[_0x2ebfe5(0x17f)]),![];console['log'](_0x2ebfe5(0x166));const _0x41abda=await _0x2a824f['ARjsM'](isMarketplaceAdded,'trailhead');let _0x29eef1=_0x41abda;if(_0x41abda)console['log']('✓\x20Marketplace\x20already\x20added');else{const _0x3eb48c=await _0x2a824f[_0x2ebfe5(0x199)](runClaudeCommand,[_0x2a824f[_0x2ebfe5(0x1a2)],'marketplace',_0x2a824f[_0x2ebfe5(0x16c)],_0x2a824f['dRzIU']]);!_0x3eb48c['success']?(console['error']('Failed\x20to\x20add\x20marketplace:',_0x3eb48c[_0x2ebfe5(0x18d)]),console['log'](_0x2ebfe5(0x174))):_0x29eef1=!![];}if(_0x29eef1){const _0x41956b=await _0x2a824f['OGZWu'](runClaudeCommand,[_0x2a824f[_0x2ebfe5(0x1a2)],_0x2a824f['ThNlq'],_0x2ebfe5(0x163),'--scope',_0x2ebfe5(0x176)]);!_0x41956b[_0x2ebfe5(0x186)]?(console['error'](_0x2a824f['DOTSw'],_0x41956b['error']),console[_0x2ebfe5(0x198)]('You\x20can\x20install\x20manually:\x20claude\x20plugin\x20install\x20ranger@trailhead\x20--scope\x20project')):console['log'](_0x2a824f['GRrVt']);}return!![];}export async function setupCi(_0xf1be69,_0xeadcf3,_0x3f9355){const _0x7cf792=_0x48b8,_0x3e5770={'MTxvb':function(_0x5f1628,_0x4735f6){return _0x5f1628(_0x4735f6);},'HsKmO':_0x7cf792(0x18c),'TrJbl':function(_0x4caf20){return _0x4caf20();},'xQzBn':function(_0x16de65,_0x345de4,_0x11c07b){return _0x16de65(_0x345de4,_0x11c07b);},'vZXWm':_0x7cf792(0x189),'clJRH':_0x7cf792(0x180),'JLtVP':function(_0x25799b){return _0x25799b();},'pdFwI':function(_0x55fb11,_0x40e2f6,_0x3b1187){return _0x55fb11(_0x40e2f6,_0x3b1187);},'mRSTH':function(_0x122bde,_0x42c1f3,_0x12041f){return _0x122bde(_0x42c1f3,_0x12041f);},'GcGPI':function(_0x56f095,_0x1f32cd){return _0x56f095(_0x1f32cd);},'ndTDq':function(_0xc40ac5,_0x3f4e05,_0x5986b9){return _0xc40ac5(_0x3f4e05,_0x5986b9);},'ApoCl':function(_0x488f83,_0x474674){return _0x488f83(_0x474674);},'Qmxxt':_0x7cf792(0x19a),'lcAnp':function(_0x2a218b,_0x4bbedc){return _0x2a218b instanceof _0x4bbedc;},'XCDAS':_0x7cf792(0x169),'AMiCk':'plugin','CnXmE':function(_0x3fdf95){return _0x3fdf95();},'QmEqH':'skills'};console['log'](_0x7cf792(0x18a)),_0x3f9355?.['trackPhaseStart'](_0x7cf792(0x18c)),await _0x3e5770[_0x7cf792(0x16a)](authenticate,_0xf1be69),_0x3f9355?.[_0x7cf792(0x184)](_0x3e5770[_0x7cf792(0x16f)]),_0x3f9355?.[_0x7cf792(0x17e)](_0x7cf792(0x19b));const {path:_0x23b517,installed:_0x29939a}=await _0x3e5770[_0x7cf792(0x187)](ensureRangerDir);await _0x3e5770['MTxvb'](writeRangerGitignore,_0x23b517);const _0x35d6e8=join(_0x23b517,'sessions');!existsSync(_0x35d6e8)&&await _0x3e5770[_0x7cf792(0x192)](mkdir,_0x35d6e8,{'recursive':!![]});_0x3f9355?.[_0x7cf792(0x184)](_0x7cf792(0x19b),{'installed':_0x29939a}),_0x3f9355?.[_0x7cf792(0x17e)](_0x3e5770['vZXWm']);let _0x5db799=![];_0xeadcf3?.[_0x7cf792(0x165)]?console['log'](_0x3e5770['clJRH']):_0x5db799=await _0x3e5770[_0x7cf792(0x1a3)](ensureChromium);_0x3f9355?.['trackPhaseEnd'](_0x3e5770['vZXWm'],{'installed':_0x5db799,'skipped':!!_0xeadcf3?.[_0x7cf792(0x165)]}),_0x3f9355?.['trackPhaseStart']('profile_activate');const _0x41be97=await findCiProfile(_0xeadcf3?.[_0x7cf792(0x17b)]);let _0x42d625=![];_0xeadcf3?.[_0x7cf792(0x17c)]&&(await _0x3e5770['pdFwI'](mkdir,_0x41be97['path'],{'recursive':!![]}),await saveSettings(_0x41be97[_0x7cf792(0x171)],{'baseUrl':_0xeadcf3['baseUrl'],'headless':!![]}),console[_0x7cf792(0x198)]('✓\x20Created\x20profile\x20settings:\x20baseUrl='+_0xeadcf3['baseUrl']),_0x42d625=!![]);const _0x237747=_0x3e5770['mRSTH'](join,_0x41be97['path'],_0x7cf792(0x179));if(!_0x3e5770['GcGPI'](existsSync,_0x237747)&&!_0x42d625)throw new Error(_0x7cf792(0x194)+_0x41be97['name']+'\x22\x20has\x20no\x20settings.json.\x20Use\x20--base-url\x20to\x20configure\x20it.');const _0x227e59=_0x3e5770[_0x7cf792(0x1a1)](join,_0x41be97['path'],_0x7cf792(0x185)),_0x539ec1=_0x3e5770['ndTDq'](join,_0x41be97['path'],'auth.json.enc'),_0x504a8a=existsSync(_0x227e59),_0x3de929=_0x3e5770['GcGPI'](existsSync,_0x539ec1);if(_0x3de929)try{const _0x5ed41f=await getToken();if(!_0x5ed41f)throw new Error(_0x7cf792(0x19f));const _0x14d17a=await _0x3e5770[_0x7cf792(0x183)](readFile,_0x539ec1);_0x3e5770[_0x7cf792(0x19d)](decrypt,_0x14d17a,_0x5ed41f),console[_0x7cf792(0x198)](_0x3e5770[_0x7cf792(0x197)]);}catch(_0x50bbfd){const _0x2f007f=_0x3e5770['lcAnp'](_0x50bbfd,Error)?_0x50bbfd[_0x7cf792(0x19e)]:String(_0x50bbfd);throw new Error('Failed\x20to\x20verify\x20encrypted\x20auth\x20for\x20profile\x20\x22'+_0x41be97[_0x7cf792(0x171)]+'\x22:\x20'+_0x2f007f);}else _0x504a8a?console['log'](_0x7cf792(0x18e)):console[_0x7cf792(0x198)](_0x7cf792(0x16e));await writeActiveProfileName(_0x41be97[_0x7cf792(0x171)]),console[_0x7cf792(0x198)]('✓\x20Active\x20profile:\x20'+_0x41be97['name']),_0x3f9355?.[_0x7cf792(0x184)](_0x3e5770[_0x7cf792(0x188)],{'profileName':_0x41be97[_0x7cf792(0x171)],'hasAuth':_0x504a8a,'hasEncryptedAuth':_0x3de929,'createdSettings':_0x42d625}),_0x3f9355?.[_0x7cf792(0x17e)](_0x3e5770[_0x7cf792(0x193)]);const _0xb1783f=await _0x3e5770[_0x7cf792(0x17d)](installPluginNonInteractive);_0x3f9355?.[_0x7cf792(0x184)](_0x7cf792(0x175),{'installed':_0xb1783f}),_0x3f9355?.[_0x7cf792(0x17e)](_0x3e5770[_0x7cf792(0x167)]),await skillup({'autoInstall':_0x7cf792(0x176)}),_0x3f9355?.['trackPhaseEnd']('skills'),console[_0x7cf792(0x198)]('\x0a✅\x20Ranger\x20CI\x20setup\x20complete!\x0a');}
@@ -1,80 +1 @@
1
- import { basename } from 'path';
2
- import inquirer from 'inquirer';
3
- import { getToken } from './utils/keychain.js';
4
- import { installSkill } from './utils/skills.js';
5
- import { getCurrentVersion } from './utils/version.js';
6
- import { getClaudeConfigDir, getProjectRoot, } from './utils/claudeConfig.js';
7
- export async function skillup(options = {}) {
8
- console.log('\n🎯 Ranger Skill Setup\n');
9
- const token = await getToken();
10
- if (!token) {
11
- console.log('❌ No Ranger API token found.\n');
12
- console.log('To get started:');
13
- console.log(' 1. Get your API token from https://dashboard.ranger.net/cli');
14
- console.log(' 2. Run: ranger setup <your-api-token>');
15
- console.log(' 3. Run: ranger skillup\n');
16
- return;
17
- }
18
- console.log('✓ Found API token');
19
- const projectRoot = getProjectRoot();
20
- const projectName = basename(projectRoot);
21
- // Determine install level
22
- const isInteractive = process.stdin.isTTY && process.stdout.isTTY;
23
- let installLevel;
24
- if (options.autoInstall) {
25
- installLevel = options.autoInstall;
26
- }
27
- else if (isInteractive) {
28
- const response = await inquirer.prompt([
29
- {
30
- type: 'list',
31
- name: 'installLevel',
32
- message: 'Where should skills be installed?',
33
- choices: [
34
- {
35
- name: `All projects (${getClaudeConfigDir()}/skills/)`,
36
- value: 'user',
37
- },
38
- {
39
- name: `This project only (${projectName}/.claude/skills/)`,
40
- value: 'project',
41
- },
42
- ],
43
- },
44
- ]);
45
- installLevel = response.installLevel;
46
- }
47
- else {
48
- // Non-interactive mode: default to project-level installation
49
- installLevel = 'project';
50
- console.log(`Non-interactive mode: Installing skills at project level (${projectName}/.claude/skills/)`);
51
- }
52
- let installedCount = 0;
53
- const cliVersion = getCurrentVersion();
54
- console.log('\n📦 Installing skills...\n');
55
- // Install ranger (requires API token)
56
- try {
57
- const featureTrackerInstalled = await installSkill('ranger', {
58
- cliVersion,
59
- level: installLevel,
60
- });
61
- if (featureTrackerInstalled) {
62
- installedCount++;
63
- }
64
- }
65
- catch (error) {
66
- console.warn(' Failed to install ranger skill:', error instanceof Error ? error.message : error);
67
- }
68
- if (installedCount > 0) {
69
- const levelDesc = installLevel === 'user' ? 'user-level' : 'project-level';
70
- console.log(`\n✅ Installed ${installedCount} ${levelDesc} skill${installedCount > 1 ? 's' : ''} successfully!\n`);
71
- if (!options.suppressUsage) {
72
- console.log('To use:');
73
- console.log(` - Open Claude Code in plan mode and run /ranger:enable. Plan out a UI feature with Ranger and watch Ranger test it for you!`);
74
- }
75
- }
76
- else {
77
- console.log('\n⚠️ No skills were installed.\n');
78
- }
79
- }
80
- //# sourceMappingURL=skillup.js.map
1
+ function _0xfc37(){const _0x37442c=['To\x20get\x20started:','project','RRgAo','warn','5682870KuaJrz','\x20\x201.\x20Get\x20your\x20API\x20token\x20from\x20https://dashboard.ranger.net/cli','249604sWsaaM','488QEnXRt','split','list','\x20skill','aSmAk','ZroxZ','\x20\x203.\x20Run:\x20ranger\x20skillup\x0a','tGTnC','LhSeT','autoInstall','68841KabsvB','GwOKn','✓\x20Found\x20API\x20token','84LYtCzY','QdGxA','\x0a✅\x20Installed\x20','xBWCl','\x0a🎯\x20Ranger\x20Skill\x20Setup\x0a','9750530JcZjna','254990WpnoAw','aYuyW','Where\x20should\x20skills\x20be\x20installed?','suppressUsage','isTTY','ranger','47266GeLdqi','log','vKHrQ','kXVFA','RIbUX','❌\x20No\x20Ranger\x20API\x20token\x20found.\x0a','1065841FdZslS','55QKjBHv'];_0xfc37=function(){return _0x37442c;};return _0xfc37();}(function(_0xff02ce,_0x2415e2){const _0x55f19c=_0x24f1,_0xec451e=_0xff02ce();while(!![]){try{const _0x3a7192=parseInt(_0x55f19c(0x1d1))/0x1+parseInt(_0x55f19c(0x1d7))/0x2*(parseInt(_0x55f19c(0x1cb))/0x3)+-parseInt(_0x55f19c(0x1e5))/0x4*(parseInt(_0x55f19c(0x1de))/0x5)+-parseInt(_0x55f19c(0x1e3))/0x6+-parseInt(_0x55f19c(0x1dd))/0x7+parseInt(_0x55f19c(0x1e6))/0x8*(parseInt(_0x55f19c(0x1c8))/0x9)+parseInt(_0x55f19c(0x1d0))/0xa;if(_0x3a7192===_0x2415e2)break;else _0xec451e['push'](_0xec451e['shift']());}catch(_0x1c0cb1){_0xec451e['push'](_0xec451e['shift']());}}}(_0xfc37,0x8bc79));import{basename}from'path';import _0x411801 from'inquirer';import{getToken}from'./utils/keychain.js';function _0x24f1(_0x39ecee,_0xd3df6b){_0x39ecee=_0x39ecee-0x1c1;const _0xfc37ee=_0xfc37();let _0x24f1cc=_0xfc37ee[_0x39ecee];return _0x24f1cc;}import{installSkill}from'./utils/skills.js';import{getCurrentVersion}from'./utils/version.js';import{getClaudeConfigDir,getProjectRoot}from'./utils/claudeConfig.js';export async function skillup(_0x5abbe4={}){const _0x2edf33=_0x24f1,_0x3ecbf4={'RIbUX':function(_0x2855ac){return _0x2855ac();},'vKHrQ':'5|4|2|0|1|3','uelYp':'\x20\x202.\x20Run:\x20ranger\x20setup\x20<your-api-token>','QdGxA':_0x2edf33(0x1dc),'ZroxZ':_0x2edf33(0x1ca),'kXVFA':function(_0x5b32bb,_0x542d1c){return _0x5b32bb(_0x542d1c);},'geJsm':_0x2edf33(0x1e8),'tGTnC':_0x2edf33(0x1d3),'LhSeT':'user','aYuyW':function(_0x1c19e2,_0x187704,_0xa42799){return _0x1c19e2(_0x187704,_0xa42799);},'xBWCl':_0x2edf33(0x1d6),'hlJjj':'\x20\x20Failed\x20to\x20install\x20ranger\x20skill:','RRgAo':function(_0x336494,_0x3b76a7){return _0x336494 instanceof _0x3b76a7;},'LGFlj':function(_0xcc29cd,_0x426741){return _0xcc29cd>_0x426741;},'aSmAk':function(_0x55ba86,_0x53dac2){return _0x55ba86>_0x53dac2;},'GwOKn':'\x0a⚠️\x20\x20No\x20skills\x20were\x20installed.\x0a'};console[_0x2edf33(0x1d8)](_0x2edf33(0x1cf));const _0x261905=await _0x3ecbf4[_0x2edf33(0x1db)](getToken);if(!_0x261905){const _0x37e3cb=_0x3ecbf4[_0x2edf33(0x1d9)][_0x2edf33(0x1e7)]('|');let _0x3910e4=0x0;while(!![]){switch(_0x37e3cb[_0x3910e4++]){case'0':console['log'](_0x3ecbf4['uelYp']);continue;case'1':console[_0x2edf33(0x1d8)](_0x2edf33(0x1c4));continue;case'2':console['log'](_0x2edf33(0x1e4));continue;case'3':return;case'4':console['log'](_0x2edf33(0x1df));continue;case'5':console['log'](_0x3ecbf4[_0x2edf33(0x1cc)]);continue;}break;}}console['log'](_0x3ecbf4[_0x2edf33(0x1c3)]);const _0x5bef2c=getProjectRoot(),_0xd6ca49=_0x3ecbf4[_0x2edf33(0x1da)](basename,_0x5bef2c),_0x480e24=process['stdin'][_0x2edf33(0x1d5)]&&process['stdout']['isTTY'];let _0x34b1c0;if(_0x5abbe4['autoInstall'])_0x34b1c0=_0x5abbe4[_0x2edf33(0x1c7)];else{if(_0x480e24){const _0xd1c2bc=await _0x411801['prompt']([{'type':_0x3ecbf4['geJsm'],'name':'installLevel','message':_0x3ecbf4[_0x2edf33(0x1c5)],'choices':[{'name':'All\x20projects\x20('+getClaudeConfigDir()+'/skills/)','value':_0x3ecbf4['LhSeT']},{'name':'This\x20project\x20only\x20('+_0xd6ca49+'/.claude/skills/)','value':_0x2edf33(0x1e0)}]}]);_0x34b1c0=_0xd1c2bc['installLevel'];}else _0x34b1c0=_0x2edf33(0x1e0),console['log']('Non-interactive\x20mode:\x20Installing\x20skills\x20at\x20project\x20level\x20('+_0xd6ca49+'/.claude/skills/)');}let _0xe6fe83=0x0;const _0xd0c508=getCurrentVersion();console['log']('\x0a📦\x20Installing\x20skills...\x0a');try{const _0x3c16e8=await _0x3ecbf4[_0x2edf33(0x1d2)](installSkill,_0x3ecbf4[_0x2edf33(0x1ce)],{'cliVersion':_0xd0c508,'level':_0x34b1c0});_0x3c16e8&&_0xe6fe83++;}catch(_0x6cb015){console[_0x2edf33(0x1e2)](_0x3ecbf4['hlJjj'],_0x3ecbf4[_0x2edf33(0x1e1)](_0x6cb015,Error)?_0x6cb015['message']:_0x6cb015);}if(_0x3ecbf4['LGFlj'](_0xe6fe83,0x0)){const _0x139b13=_0x34b1c0===_0x3ecbf4[_0x2edf33(0x1c6)]?'user-level':'project-level';console[_0x2edf33(0x1d8)](_0x2edf33(0x1cd)+_0xe6fe83+'\x20'+_0x139b13+_0x2edf33(0x1c1)+(_0x3ecbf4[_0x2edf33(0x1c2)](_0xe6fe83,0x1)?'s':'')+'\x20successfully!\x0a'),!_0x5abbe4[_0x2edf33(0x1d4)]&&(console['log']('To\x20use:'),console['log']('\x20\x20-\x20Open\x20Claude\x20Code\x20in\x20plan\x20mode\x20and\x20run\x20/ranger:enable.\x20Plan\x20out\x20a\x20UI\x20feature\x20with\x20Ranger\x20and\x20watch\x20Ranger\x20test\x20it\x20for\x20you!'));}else console['log'](_0x3ecbf4[_0x2edf33(0x1c9)]);}