@remits/remits-cli 0.1.100 → 0.1.101

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
@@ -16,6 +16,7 @@ On each command run, `remits-cli` checks the npm `latest` version for `@remits/r
16
16
  remits-cli auth --base-url https://your-remits-host --account-id 123
17
17
  remits-cli start
18
18
  remits-cli status
19
+ remits-cli whoami
19
20
  remits-cli stop
20
21
  remits-cli install --skills
21
22
  remits-cli tools
@@ -97,7 +98,8 @@ remits-cli install --skills --overwrite true
97
98
  - Most non-lifecycle commands auto-start the background service if authenticated sessions already exist and no service is running.
98
99
  - Successful `remits-cli auth` also attempts to auto-start the background service.
99
100
  - `remits-cli start` starts a detached background process by default. Use `remits-cli start --foreground true` only when you want to run the daemon in the current terminal.
100
- - `remits-cli status` reports whether the background service is alive and prints the dashboard URL when available.
101
+ - `remits-cli status` reports whether the background service is alive, prints the dashboard URL when available, and prints the resolved session tuple: Account ID, User ID, current git branch, and active data mode.
102
+ - `remits-cli whoami` prints only the resolved session tuple. Use `--base-url`, `--account-id`, and `--data-mode` to prove the exact host/account/lane before running a tool or test.
101
103
  - `remits-cli stop` stops the background service, kills the shared tmux session, and clears pane tracking state.
102
104
  - The service starts a localhost dashboard that acts as a control center for remits-cli integration state.
103
105
  - The dashboard shows websocket connection health, topic subscriptions, tmux session/panes, the discovered account repo index, global state files, and per-repo remits-cli files.
package/index.js CHANGED
@@ -278,6 +278,110 @@ function printResolvedBaseUrl(baseUrl) {
278
278
  console.log('Base URL:', normalizeBaseUrl(baseUrl || DEFAULT_BASE_URL));
279
279
  }
280
280
 
281
+ function accountNameFromAccountInfo(info) {
282
+ return (info && (
283
+ (info.resolution && info.resolution.accountName) ||
284
+ (info.repoContext && info.repoContext.accountInfoAccountName) ||
285
+ info.name ||
286
+ info.accountName ||
287
+ (info.account && info.account.name)
288
+ )) || null;
289
+ }
290
+
291
+ function resolveSessionIdentity(cwd, flags = {}) {
292
+ let accountId = null;
293
+ const fromFlag = Number(flags['account-id']);
294
+ if (Number.isFinite(fromFlag) && fromFlag > 0) {
295
+ accountId = fromFlag;
296
+ }
297
+
298
+ const accountInfo = loadAccountInfo(cwd);
299
+ if (!accountId && accountInfo) {
300
+ accountId = Number(accountIdFromAccountInfo(accountInfo));
301
+ try { updateAccountRepoIndex(cwd); } catch (_) { /* best-effort */ }
302
+ }
303
+
304
+ const requestedBaseUrl = flags['base-url'] ? normalizeBaseUrl(flags['base-url']) : null;
305
+ const requestedDataMode = hasExplicitDataModeFlag(flags) ? resolveDataMode(flags, null) : null;
306
+ const session = readSession({
307
+ accountId,
308
+ baseUrl: requestedBaseUrl,
309
+ dataMode: requestedDataMode
310
+ }, {
311
+ strictBaseUrl: Boolean(requestedBaseUrl),
312
+ strictDataMode: Boolean(requestedDataMode)
313
+ });
314
+
315
+ if (!accountId && session && session.accountId) {
316
+ accountId = Number(session.accountId);
317
+ }
318
+
319
+ const dataMode = requestedDataMode || resolveDataMode(flags, session);
320
+ const branchName = flags.branch || flags.branchName || currentBranch(cwd);
321
+ const user = session && session.user ? session.user : {};
322
+ const repoName = accountNameFromAccountInfo(accountInfo);
323
+ const localAccountInfoAccountId = accountInfo ? Number(accountIdFromAccountInfo(accountInfo)) : null;
324
+ const sessionResolutionWarning = session
325
+ ? buildSessionResolutionWarning(accountId, requestedBaseUrl, session)
326
+ : null;
327
+
328
+ return {
329
+ authenticated: Boolean(session && session.token),
330
+ accountId: accountId || (session && session.accountId) || null,
331
+ accountName: (session && session.account && session.account.name) || null,
332
+ localAccountName: repoName,
333
+ localAccountInfoAccountId: Number.isFinite(localAccountInfoAccountId) ? localAccountInfoAccountId : null,
334
+ userId: user.id || session?.userId || null,
335
+ userName: user.name || user.username || user.email || null,
336
+ branchName,
337
+ dataMode,
338
+ baseUrl: normalizeBaseUrl((session && session.baseUrl) || requestedBaseUrl || DEFAULT_BASE_URL),
339
+ updatedAt: session ? session.updatedAt : null,
340
+ sessionResolutionWarning
341
+ };
342
+ }
343
+
344
+ function printSessionIdentity(identity, options = {}) {
345
+ if (options.json) {
346
+ console.log(JSON.stringify(identity, null, 2));
347
+ return;
348
+ }
349
+
350
+ if (!identity.authenticated) {
351
+ console.log('Active session: not authenticated');
352
+ console.log('Account ID:', identity.accountId || 'unresolved');
353
+ console.log('User ID:', 'unresolved');
354
+ console.log('Branch:', identity.branchName || 'unresolved');
355
+ console.log('Data mode:', identity.dataMode || DEFAULT_DATA_MODE);
356
+ console.log('Base URL:', identity.baseUrl);
357
+ return;
358
+ }
359
+
360
+ console.log('Active session:');
361
+ console.log(' Account ID:', identity.accountId);
362
+ if (identity.accountName) {
363
+ console.log(' Account:', identity.accountName);
364
+ }
365
+ if (identity.localAccountName) {
366
+ let localDetails = identity.localAccountInfoAccountId ? 'id ' + identity.localAccountInfoAccountId : '';
367
+ if (identity.localAccountInfoAccountId && identity.accountId &&
368
+ Number(identity.localAccountInfoAccountId) !== Number(identity.accountId)) {
369
+ localDetails += '; command targets account ' + identity.accountId;
370
+ }
371
+ console.log(' Local repo account:', identity.localAccountName + (localDetails ? ' (' + localDetails + ')' : ''));
372
+ }
373
+ console.log(' User ID:', identity.userId || 'unknown');
374
+ if (identity.userName) {
375
+ console.log(' User:', identity.userName);
376
+ }
377
+ console.log(' Branch:', identity.branchName);
378
+ console.log(' Data mode:', identity.dataMode);
379
+ console.log(' Base URL:', identity.baseUrl);
380
+ if (identity.updatedAt) {
381
+ console.log(' Session updated:', identity.updatedAt);
382
+ }
383
+ }
384
+
281
385
  // Tools/actions whose names signal they mutate state rather than only reading it. Used solely to make
282
386
  // data-lane banners precise — never to block or permit anything.
283
387
  const MUTATING_TOOL_PATTERN = /(^|_)(patch|edit|create|commit|update|delete|remove|write|set|assign|run|execute|send|pause|unpause|interrupt|restore|repair|migrate|sync)(_|$)/i;
@@ -5333,8 +5437,28 @@ async function waitForListenerStopped(timeoutMs = 5000) {
5333
5437
  return !isListenerRunning();
5334
5438
  }
5335
5439
 
5336
- async function listenStatusCommand() {
5440
+ async function listenStatusCommand(flags = {}) {
5441
+ const wantsJson = flagEnabled(flags.json);
5337
5442
  const state = readServiceState();
5443
+ const identity = resolveSessionIdentity(process.cwd(), flags);
5444
+
5445
+ if (wantsJson) {
5446
+ console.log(JSON.stringify({
5447
+ service: {
5448
+ running: isListenerRunning(),
5449
+ pid: isListenerRunning() && fs.existsSync(LISTENER_PID_FILE)
5450
+ ? fs.readFileSync(LISTENER_PID_FILE, 'utf8').trim()
5451
+ : null,
5452
+ dashboardUrl: state.dashboardUrl || null,
5453
+ indexedRepos: state.discovery && Number.isFinite(state.discovery.repoCount)
5454
+ ? state.discovery.repoCount
5455
+ : null
5456
+ },
5457
+ session: identity
5458
+ }, null, 2));
5459
+ return;
5460
+ }
5461
+
5338
5462
  if (isListenerRunning()) {
5339
5463
  const pid = fs.readFileSync(LISTENER_PID_FILE, 'utf8').trim();
5340
5464
  console.log('remits-cli service is running (pid: ' + pid + ')');
@@ -5347,6 +5471,14 @@ async function listenStatusCommand() {
5347
5471
  } else {
5348
5472
  console.log('remits-cli service is not running.');
5349
5473
  }
5474
+ printSessionResolutionWarning(identity);
5475
+ printSessionIdentity(identity);
5476
+ }
5477
+
5478
+ async function whoamiCommand(flags = {}) {
5479
+ const identity = resolveSessionIdentity(process.cwd(), flags);
5480
+ printSessionResolutionWarning(identity);
5481
+ printSessionIdentity(identity, { json: flagEnabled(flags.json) });
5350
5482
  }
5351
5483
 
5352
5484
  function npmCommand() {
@@ -5618,7 +5750,7 @@ async function main() {
5618
5750
 
5619
5751
  // Auto-start the background service if not already running.
5620
5752
  // Skip for lifecycle subcommands and help.
5621
- const isLifecycleCmd = command === 'listen' || command === 'start' || command === 'stop' || command === 'status';
5753
+ const isLifecycleCmd = command === 'listen' || command === 'start' || command === 'stop' || command === 'status' || command === 'whoami';
5622
5754
  const isHelpCmd = !command || command === 'help' || command === '--help' || wantsHelp;
5623
5755
  if (!wantsJson && !isHelpCmd && !isLifecycleCmd && !isListenerRunning()) {
5624
5756
  try {
@@ -5647,7 +5779,8 @@ async function main() {
5647
5779
  console.log(' remits-cli config [set] [--agent claude|codex|gemini]');
5648
5780
  console.log(' remits-cli start [--foreground true] [--port 8787]');
5649
5781
  console.log(' remits-cli stop');
5650
- console.log(' remits-cli status');
5782
+ console.log(' remits-cli status [--base-url URL] [--account-id ID] [--data-mode test|prod] [--json]');
5783
+ console.log(' remits-cli whoami [--base-url URL] [--account-id ID] [--data-mode test|prod] [--json]');
5651
5784
  console.log(' remits-cli listen [stop|status] [--foreground true] # compatibility alias');
5652
5785
  console.log(' remits-cli data-mode [set test|prod]');
5653
5786
  console.log(' remits-cli install --skills [--target codex|claude|gemini|all] [--overwrite true]');
@@ -5759,7 +5892,7 @@ async function main() {
5759
5892
  return;
5760
5893
  }
5761
5894
  if (subcommand === 'status') {
5762
- await listenStatusCommand();
5895
+ await listenStatusCommand(args);
5763
5896
  return;
5764
5897
  }
5765
5898
  await listenCommand(args);
@@ -5777,7 +5910,12 @@ async function main() {
5777
5910
  }
5778
5911
 
5779
5912
  if (command === 'status') {
5780
- await listenStatusCommand();
5913
+ await listenStatusCommand(args);
5914
+ return;
5915
+ }
5916
+
5917
+ if (command === 'whoami') {
5918
+ await whoamiCommand(args);
5781
5919
  return;
5782
5920
  }
5783
5921
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@remits/remits-cli",
3
- "version": "0.1.100",
3
+ "version": "0.1.101",
4
4
  "description": "Local CLI for auth, component sync, and live test execution against Remits",
5
5
  "license": "MIT",
6
6
  "private": false,
@@ -2448,6 +2448,11 @@ remits-cli sessions remove --account-id 42 --base-url http://localhost:8080
2448
2448
 
2449
2449
  You can work in multiple account repos simultaneously across different terminal windows — each uses its own session. You can also be authenticated against different base URLs (e.g., localhost for development and production) for the same account at the same time.
2450
2450
 
2451
+ Use `remits-cli whoami` when you need a compact proof of the active target before a sensitive operation.
2452
+ It prints the resolved Account ID, User ID, current git branch, data mode, and base URL. `remits-cli status`
2453
+ prints the same session tuple after the service/dashboard status. Pass `--base-url`, `--account-id`, and
2454
+ `--data-mode` when host or lane matters; do not infer those values from the repo directory or account name.
2455
+
2451
2456
  ## Persistent Service, Control Center, and Agent Dispatch
2452
2457
 
2453
2458
  The current mental model is a **background remits-cli service**, not just a listener.
@@ -2463,6 +2468,7 @@ That service does three jobs:
2463
2468
  remits-cli start
2464
2469
  remits-cli start --foreground true
2465
2470
  remits-cli status
2471
+ remits-cli whoami
2466
2472
  remits-cli stop
2467
2473
  ```
2468
2474
 
@@ -2586,7 +2592,8 @@ remits-cli sessions [list|remove] [--account-id ID]
2586
2592
  remits-cli config [set] [--agent claude|codex|gemini]
2587
2593
  remits-cli start [--foreground true] [--port 8787]
2588
2594
  remits-cli stop
2589
- remits-cli status
2595
+ remits-cli status [--base-url URL] [--account-id ID] [--data-mode test|prod] [--json]
2596
+ remits-cli whoami [--base-url URL] [--account-id ID] [--data-mode test|prod] [--json]
2590
2597
  remits-cli listen [stop|status] [--foreground true] # compatibility alias
2591
2598
  remits-cli data-mode [set test|prod]
2592
2599
  remits-cli components stage [--branch <name>] [--data-mode test|prod] [--json|--verbose]