@lotics/cli 0.96.2 → 0.96.4

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
@@ -72,6 +72,8 @@ lotics org use acme # switch active org by name (or org id)
72
72
  lotics org use "Acme Corp" # names are case-insensitive
73
73
  ```
74
74
 
75
+ The org **id** is the identity; the name is a label cached when the key was saved. Rename an org in the app and the cached label goes stale — the old name still works, the new one matches nothing — until `lotics auth whoami` refreshes it. A name matching two saved orgs is refused rather than guessed; use the id.
76
+
75
77
  ### Working in parallel (worktrees)
76
78
 
77
79
  Pin a directory to its own org/workspace so a global `org use` elsewhere never disturbs it. The pin is a pointer — the key still comes from the global store, so there's nothing to paste:
@@ -82,7 +84,9 @@ lotics org use acme --local # writes ./.lotics/config.json { active_org
82
84
  lotics workspace select wks_... # records the workspace in the local pin
83
85
  ```
84
86
 
85
- Each worktree resolves independently; switching the global default in another shell leaves pinned worktrees untouched. Use `lotics auth whoami` to see the active org, workspace, and which source resolved them. `.lotics/` should be gitignored.
87
+ Each worktree resolves independently; switching the global default in another shell leaves pinned worktrees untouched. `.lotics/` should be gitignored.
88
+
89
+ Every command names its target before it acts — `lotics → <org> / <workspace>` on **stderr**, so stdout stays clean for piping. When nothing in the directory or environment chose the org and it came from the machine-wide default, the line says so and prints the `--local` command to pin — that default is the one another shell can move between two of your commands. `lotics auth whoami` reports the same resolution on demand, including which source won.
86
90
 
87
91
  ### Resolution precedence
88
92
 
@@ -52894,7 +52894,7 @@ ${e.toString()}`);
52894
52894
  const contentChars = maxContentWidth.get(c) ?? 0;
52895
52895
  const hidden = colHidden.has(c);
52896
52896
  let width;
52897
- if (excelWidth && excelWidth > 8) {
52897
+ if (excelWidth !== void 0 && excelWidth > 0) {
52898
52898
  width = excelWidth;
52899
52899
  } else {
52900
52900
  width = Math.max(8, Math.min(contentChars + 2, 40));
package/dist/src/cli.js CHANGED
@@ -45219,23 +45219,23 @@ function setActiveOrg(orgId, scope) {
45219
45219
  const config2 = loadGlobalConfig() ?? {};
45220
45220
  saveGlobalConfig({ ...config2, active_org: orgId });
45221
45221
  }
45222
- function setSelectedWorkspace(workspaceId) {
45222
+ function setSelectedWorkspace(workspaceId, resolvedOrgId) {
45223
+ if (!resolvedOrgId) return null;
45223
45224
  const local = loadLocalConfig();
45224
- if (local?.active_org) {
45225
+ if (local?.active_org === resolvedOrgId) {
45225
45226
  saveConfig({ ...local, workspace_id: workspaceId }, "auto");
45226
45227
  return { scope: "local", orgId: local.active_org };
45227
45228
  }
45228
45229
  const config2 = loadGlobalConfig() ?? {};
45229
- const orgId = config2.active_org;
45230
- const profile = orgId ? config2.profiles?.[orgId] : void 0;
45231
- if (!orgId || !profile) {
45230
+ const profile = config2.profiles?.[resolvedOrgId];
45231
+ if (!profile) {
45232
45232
  return null;
45233
45233
  }
45234
45234
  saveGlobalConfig({
45235
45235
  ...config2,
45236
- profiles: { ...config2.profiles, [orgId]: { ...profile, workspace_id: workspaceId } }
45236
+ profiles: { ...config2.profiles, [resolvedOrgId]: { ...profile, workspace_id: workspaceId } }
45237
45237
  });
45238
- return { scope: "global", orgId };
45238
+ return { scope: "global", orgId: resolvedOrgId };
45239
45239
  }
45240
45240
  var UPDATE_CHECK_INTERVAL_MS = 24 * 60 * 60 * 1e3;
45241
45241
  function checkForUpdate(currentVersion) {
@@ -79151,7 +79151,7 @@ function buildColumns(colDefs, colHidden, maxContentWidth, colCount, _defaultCol
79151
79151
  const contentChars = maxContentWidth.get(c) ?? 0;
79152
79152
  const hidden = colHidden.has(c);
79153
79153
  let width;
79154
- if (excelWidth && excelWidth > 8) {
79154
+ if (excelWidth !== void 0 && excelWidth > 0) {
79155
79155
  width = excelWidth;
79156
79156
  } else {
79157
79157
  width = Math.max(8, Math.min(contentChars + 2, 40));
@@ -91531,8 +91531,20 @@ var SOURCE_LABELS = {
91531
91531
  local_pointer: "local .lotics/config.json (pin)",
91532
91532
  global_profile: "global active profile"
91533
91533
  };
91534
+ function announceTarget(ctx, workspaceId) {
91535
+ const org = ctx.orgName ?? ctx.orgId ?? "(org from key)";
91536
+ if (ctx.source === "global_profile") {
91537
+ console.error(
91538
+ `lotics \u2192 ${org} / ${workspaceId} [globally-active org \u2014 no directory pin, no LOTICS_ORG]`
91539
+ );
91540
+ console.error(` pin this directory: lotics org use ${JSON.stringify(org)} --local`);
91541
+ return;
91542
+ }
91543
+ console.error(`lotics \u2192 ${org} / ${workspaceId}`);
91544
+ }
91534
91545
  async function resolveWorkspace(client, ctx) {
91535
91546
  if (ctx.workspaceId) {
91547
+ announceTarget(ctx, ctx.workspaceId);
91536
91548
  client.setWorkspaceId(ctx.workspaceId);
91537
91549
  return;
91538
91550
  }
@@ -91549,7 +91561,8 @@ async function resolveWorkspace(client, ctx) {
91549
91561
  process.exit(1);
91550
91562
  }
91551
91563
  if (workspaces.length === 1) {
91552
- setSelectedWorkspace(workspaces[0].id);
91564
+ setSelectedWorkspace(workspaces[0].id, ctx.orgId);
91565
+ announceTarget(ctx, workspaces[0].id);
91553
91566
  client.setWorkspaceId(workspaces[0].id);
91554
91567
  return;
91555
91568
  }
@@ -91617,6 +91630,11 @@ async function main() {
91617
91630
  const info = await client2.whoami();
91618
91631
  const existing = loadGlobalConfig() ?? {};
91619
91632
  saveGlobalConfig({ ...existing, email: info.email });
91633
+ const cached2 = existing.profiles?.[info.organization_id];
91634
+ if (cached2 && cached2.org_name !== info.organization_name) {
91635
+ upsertProfile(info.organization_id, { api_key: cached2.api_key, org_name: info.organization_name });
91636
+ console.error(`Renamed since this key was saved: "${cached2.org_name}" \u2192 "${info.organization_name}" (updated locally)`);
91637
+ }
91620
91638
  const viewAs = flags.viewAs ?? process.env.LOTICS_VIEW_AS;
91621
91639
  if (flags.json) {
91622
91640
  console.log(JSON.stringify({ ...info, workspace_id: ctx2.workspaceId ?? null, source: ctx2.source, view_as: viewAs ?? null }, null, 2));
@@ -91874,7 +91892,7 @@ Available workspaces:`);
91874
91892
  printWorkspaceList(workspaces, currentWorkspaceId);
91875
91893
  process.exit(1);
91876
91894
  }
91877
- const written = setSelectedWorkspace(target.id);
91895
+ const written = setSelectedWorkspace(target.id, ctx.orgId);
91878
91896
  if (!written) {
91879
91897
  console.error(`Switched to ${target.name} (${target.id}) for this command, but it could not be saved \u2014 credentials came from --api-key/LOTICS_API_KEY with no saved profile. Run "lotics auth api-key <key>" to persist a default.`);
91880
91898
  return;
@@ -91891,7 +91909,7 @@ Available workspaces:`);
91891
91909
  }
91892
91910
  const timezone = flags.timezone;
91893
91911
  const created = await client.createWorkspace({ name, timezone });
91894
- setSelectedWorkspace(created.id);
91912
+ setSelectedWorkspace(created.id, ctx.orgId);
91895
91913
  client.setWorkspaceId(created.id);
91896
91914
  if (flags.json) {
91897
91915
  console.log(JSON.stringify(created, null, 2));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lotics/cli",
3
- "version": "0.96.2",
3
+ "version": "0.96.4",
4
4
  "description": "Lotics SDK and CLI for AI agents",
5
5
  "type": "module",
6
6
  "bin": {