@shiplens/cli 1.4.4 → 1.4.5

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.
@@ -649,9 +649,9 @@
649
649
  "title": "Shiplens CLI One-Click Setup & Analytics Initialization",
650
650
  "suffix": "None",
651
651
  "category": "Initial Setup",
652
- "prompt": "Set up Shiplens analytics: extract project description, install SDK, create the project, and retrieve the live dashboard URL.",
652
+ "prompt": "Set up Shiplens analytics: install SDK, create the project, and retrieve the live dashboard URL.",
653
653
  "steps": [
654
- "1. Run CLI initialization command:\n- Windows: npx.cmd --yes @shiplens/cli init\n- macOS/Linux: npx --yes @shiplens/cli init",
654
+ "1. Run CLI initialization command:\n- Windows: npx.cmd --yes @shiplens/cli init --json\n- macOS/Linux: npx --yes @shiplens/cli init --json",
655
655
  "2. Present the standard project & dashboard summary (including: Project Name, App ID, Code Injection file, User Account Status, Live Dashboard / Activation URL);",
656
656
  "3. Immediately prompt the user for their email address (informing them that you will register on their behalf and Shiplens will send an activation email for 50,000 monthly free events and project binding);",
657
657
  "4. Upon receiving the user's email, run: npx.cmd --yes @shiplens/cli auth bind --email <email> --json."
@@ -660,12 +660,27 @@
660
660
  "foundation": "",
661
661
  "source": ""
662
662
  },
663
+ {
664
+ "id": "setup_bind_project",
665
+ "title": "Use Shiplens CLI to Install Analytics SDK & Link to Existing Account",
666
+ "suffix": "None",
667
+ "category": "Initial Setup",
668
+ "prompt": "Use Shiplens CLI to install the analytics SDK in this new project and link it to the user's existing Shiplens account:",
669
+ "steps": [
670
+ "1. Run the project setup & initialization command:\n- Windows: npx.cmd --yes @shiplens/cli init --json\n- macOS/Linux: npx --yes @shiplens/cli init --json",
671
+ "2. Inspect returned `user_account_status` and credential states:\n- [Branch A: Logged in & linked] (`logged_in_linked`):\n- [Branch B: No local credentials detected] (`not_logged_in_unlinked` or `activation_required=true`):\n- [Branch C: Account quota / project limit reached] (Error `QUOTA_EXCEEDED` / `PLAN_LIMIT` / unable to link):",
672
+ "3. Output the final project summary and dashboard link, confirming the project is ready for analytics queries."
673
+ ],
674
+ "commands": [],
675
+ "foundation": "",
676
+ "source": ""
677
+ },
663
678
  {
664
679
  "id": "remove_sdk",
665
- "title": "Remove Shiplens SDK & Analytics Data",
680
+ "title": "Delete Shiplens Project Analytics Data & SDK (No Longer Needed)",
666
681
  "suffix": "None",
667
682
  "category": "Initial Setup",
668
- "prompt": "Remove Shiplens SDK integration and analytics data:",
683
+ "prompt": "Delete Shiplens project analytics data and SDK integration (analytics no longer needed):",
669
684
  "steps": [
670
685
  "1. Read `.shiplens.json` in the project root to get project name, app_id, and instrumented file paths.",
671
686
  "2. Clearly display the project name and app_id to be deleted, warn the user that historical events and hosted data will be permanently purged, and pause for explicit user confirmation (\"Confirm deleting this project\").",
@@ -678,7 +693,7 @@
678
693
  },
679
694
  {
680
695
  "id": "uninstall_cli",
681
- "title": "Uninstall Shiplens CLI",
696
+ "title": "Delete Shiplens CLI",
682
697
  "suffix": "None",
683
698
  "category": "Initial Setup",
684
699
  "prompt": "Please prioritize calling Shiplens CLI (Action: uninstall_cli) to execute the above requirements. - Windows: npm.cmd uninstall -g @shiplens/cli - macOS/Linux: npm uninstall -g @shiplens/cli",
@@ -689,10 +704,10 @@
689
704
  },
690
705
  {
691
706
  "id": "generate_context",
692
- "title": "Generate Context Descriptions for All Pages and Buttons",
707
+ "title": "Use Shiplens CLI to Generate Context Descriptions for All Pages and Buttons",
693
708
  "suffix": "None",
694
709
  "category": "Initial Setup",
695
- "prompt": "Map pages, features, and button layouts into `.shiplens/contexts/<app_id>.md` so AI analytics can map numbers and IDs to concrete functionality:",
710
+ "prompt": "Use Shiplens CLI to map pages, features, and button layouts into `.shiplens/contexts/<app_id>.md` so AI analytics can understand the business context behind each metric:",
696
711
  "steps": [
697
712
  "1. Check `./.shiplens.json` for current app_id and project name.",
698
713
  "2. Inspect frontend code and routes to extract feature descriptions, user-facing copy, and button texts, locations, and actions.",
@@ -30,49 +30,29 @@ async function handleInit(args, flags, ctx) {
30
30
 
31
31
  // 1. Safety check for existing project configuration
32
32
  const existing = detectExistingApp(wd);
33
+ let isReusedExisting = false;
34
+
33
35
  if (existing.has_existing && !flags.force) {
34
- if (ctx.isJSON) {
35
- const result = {
36
- ok: false,
37
- code: 'PROJECT_EXISTS_LOCALLY',
38
- message: `Existing Shiplens configuration detected (App ID: ${existing.app_id}) in ${existing.source_file}. ` +
39
- `Option 1 [Recommended]: Keep existing statistics and project ID. ` +
40
- `Option 2: Use --force to overwrite and request a new App ID from cloud (Note: Old dashboard stops receiving new data).`,
41
- existing_app_id: existing.app_id,
42
- source_file: existing.source_file,
43
- project_name: existing.project_name || projectName,
44
- dashboard_url: `${ctx.client.baseURL}/dashboard/${existing.app_id}`,
45
- };
46
- ctx.output(result);
47
- process.exitCode = 1;
48
- return;
49
- } else if (!process.stdin.isTTY) {
50
- console.log(`\n⚠️ Existing Shiplens project detected!`);
51
- console.log(`📌 App ID: ${existing.app_id} (Source: ${existing.source_file})`);
52
- console.log(`📊 Dashboard: ${ctx.client.baseURL}/dashboard/${existing.app_id}`);
53
- console.log(`🛑 Non-interactive terminal detected (CI/Agent). Existing configuration preserved.`);
54
- console.log(`💡 Option 1 [Recommended]: Keep existing setup, retain App ID and historical statistics;`);
55
- console.log(`💡 Option 2: Overwrite with --force to create a new project:`);
56
- console.log(` npx.cmd --yes @shiplens/cli init --force\n`);
57
- return;
36
+ if (ctx.isJSON || !process.stdin.isTTY) {
37
+ // Non-interactive or JSON mode (Agent/CI): Fast-forward / Idempotent reuse of existing config
38
+ isReusedExisting = true;
58
39
  } else {
59
40
  console.log(`\n⚠️ Existing Shiplens project detected!`);
60
41
  console.log(`📌 App ID: ${existing.app_id} (Source: ${existing.source_file})`);
61
42
  console.log(`📊 Dashboard: ${ctx.client.baseURL}/dashboard/${existing.app_id}`);
62
- console.log(`\n💡 Option 1 [Recommended]: Keep existing setup, retain App ID and historical statistics;`);
63
- console.log(`💡 Option 2: Overwrite with --force to request a brand new App ID from cloud (Note: Old dashboard stops receiving new data, old and new data cannot be merged):`);
43
+ console.log(`\n💡 Option 1 [Recommended]: Keep existing setup, retain App ID and historical statistics (Press Enter or N);`);
44
+ console.log(`💡 Option 2: Overwrite with --force to request a brand new App ID from cloud (y):`);
64
45
  console.log(` npx.cmd --yes @shiplens/cli init --force\n`);
65
46
 
66
47
  const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
67
48
  const confirmed = await new Promise((resolve) => {
68
- rl.question('Overwrite and create a new project? (y/N): ', (ans) => {
49
+ rl.question('Overwrite and create a brand new project? (y/N): ', (ans) => {
69
50
  rl.close();
70
51
  resolve(ans.trim().toLowerCase() === 'y' || ans.trim().toLowerCase() === 'yes');
71
52
  });
72
53
  });
73
54
  if (!confirmed) {
74
- console.log('🛑 Operation cancelled. Existing configuration preserved.');
75
- return;
55
+ isReusedExisting = true;
76
56
  }
77
57
  }
78
58
  }
@@ -80,40 +60,52 @@ async function handleInit(args, flags, ctx) {
80
60
  // 2. Inject AI Skill (.agents/skills/shiplens/SKILL.md & Agent rules)
81
61
  const skillFile = injectSkill(wd);
82
62
 
83
- // 3. Register project on cloud
63
+ // 3. Register project on cloud (or reuse existing)
84
64
  let appId = '';
85
65
  let dashboardUrl = '';
86
66
  let accountStatus = 'not_logged_in_unlinked';
87
67
  let accountStatusText = 'Not Logged In (Default state after first installation or no valid local credentials)';
88
68
 
89
- try {
90
- const connResp = await ctx.client.connect({
91
- project_name: projectName,
92
- description,
93
- industry,
94
- genre_id: genreId,
95
- subgenre_id: subgenreId,
96
- feature_tags: featureTagIds.join(','),
97
- platform: framework,
98
- });
99
- appId = connResp.app_id;
100
- dashboardUrl = connResp.dashboard_url || `${ctx.client.baseURL}/dashboard/${appId}`;
101
-
69
+ if (isReusedExisting) {
70
+ appId = existing.app_id;
71
+ dashboardUrl = `${ctx.client.baseURL}/dashboard/${appId}`;
102
72
  if (ctx.resolvedAuth && ctx.resolvedAuth.is_present) {
103
- if (connResp.account_linked !== false && connResp.linked !== false && !connResp.unlinked) {
104
- accountStatus = 'logged_in_linked';
105
- accountStatusText = 'Logged In (Project linked to account)';
106
- } else {
107
- accountStatus = 'logged_in_unlinked';
108
- accountStatusText = 'Logged In (Project not linked to account)';
109
- }
73
+ accountStatus = 'logged_in_linked';
74
+ accountStatusText = 'Logged In (Project linked to account)';
110
75
  } else {
111
76
  accountStatus = 'not_logged_in_unlinked';
112
77
  accountStatusText = 'Not Logged In (Default state after first installation or no valid local credentials)';
113
78
  }
114
- } catch (netErr) {
115
- netErr.code = netErr.code || 'CONNECT_FAILED';
116
- throw netErr;
79
+ } else {
80
+ try {
81
+ const connResp = await ctx.client.connect({
82
+ project_name: projectName,
83
+ description,
84
+ industry,
85
+ genre_id: genreId,
86
+ subgenre_id: subgenreId,
87
+ feature_tags: featureTagIds.join(','),
88
+ platform: framework,
89
+ });
90
+ appId = connResp.app_id;
91
+ dashboardUrl = connResp.dashboard_url || `${ctx.client.baseURL}/dashboard/${appId}`;
92
+
93
+ if (ctx.resolvedAuth && ctx.resolvedAuth.is_present) {
94
+ if (connResp.account_linked !== false && connResp.linked !== false && !connResp.unlinked) {
95
+ accountStatus = 'logged_in_linked';
96
+ accountStatusText = 'Logged In (Project linked to account)';
97
+ } else {
98
+ accountStatus = 'logged_in_unlinked';
99
+ accountStatusText = 'Logged In (Project not linked to account)';
100
+ }
101
+ } else {
102
+ accountStatus = 'not_logged_in_unlinked';
103
+ accountStatusText = 'Not Logged In (Default state after first installation or no valid local credentials)';
104
+ }
105
+ } catch (netErr) {
106
+ netErr.code = netErr.code || 'CONNECT_FAILED';
107
+ throw netErr;
108
+ }
117
109
  }
118
110
 
119
111
  // 4. Inject SDK code
@@ -188,6 +180,8 @@ async function handleInit(args, flags, ctx) {
188
180
 
189
181
  const result = {
190
182
  ok: true,
183
+ reconnected: isReusedExisting,
184
+ reused_existing: isReusedExisting,
191
185
  app_id: appId,
192
186
  project_name: projectName,
193
187
  description: description || undefined,
@@ -209,12 +203,17 @@ async function handleInit(args, flags, ctx) {
209
203
  bound_email: targetEmail || undefined,
210
204
  elapsed_ms: elapsed,
211
205
  atomic_completed: true,
206
+ message: isReusedExisting
207
+ ? `Existing Shiplens project detected and successfully verified (App ID: ${appId}).`
208
+ : `Shiplens SDK successfully integrated and project created.`,
212
209
  };
213
210
 
214
211
  ctx.output(result, () => {
215
212
  console.log(`\n==================================================`);
216
- console.log(`✅ Shiplens SDK successfully integrated (${elapsed} ms)\n`);
217
- console.log(`📦 Project & Dashboard Information`);
213
+ console.log(isReusedExisting
214
+ ? `✅ Shiplens SDK verified & reconnected (${elapsed} ms)\n`
215
+ : `✅ Shiplens SDK successfully integrated (${elapsed} ms)\n`);
216
+ console.log(`📦 Project & Dashboard Information` + (isReusedExisting ? ` (Existing setup preserved)` : ''));
218
217
  console.log(`Project Name: ${projectName}`);
219
218
  if (description) {
220
219
  console.log(`Description: ${description}`);
package/lib/injector.js CHANGED
@@ -394,7 +394,7 @@ async function installSDKDependency(dir, pkgManager = 'npm') {
394
394
  },
395
395
  ];
396
396
 
397
- const TIER1_DELAY_MS = 20 * 1000; // 20s
397
+ const TIER1_DELAY_MS = 5 * 1000; // 5s (fast-forward backup mirrors on high latency)
398
398
  const TOTAL_TIMEOUT_MS = 5 * 60 * 1000; // 5min
399
399
 
400
400
  return new Promise((resolve) => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@shiplens/cli",
3
- "version": "1.4.4",
3
+ "version": "1.4.5",
4
4
  "description": "Shiplens CLI — Automated Web User Analytics & AI Agent Analysis Engine",
5
5
  "main": "lib/index.js",
6
6
  "bin": {
@@ -2,7 +2,7 @@
2
2
 
3
3
  ---
4
4
 
5
- ## Scenario Outline (42 Scenarios)
5
+ ## Scenario Outline (43 Scenarios)
6
6
 
7
7
  > **How to use**: Scan this outline to find the matching scenario, then jump to its full section below for deterministic CLI commands and analysis steps.
8
8
 
@@ -61,16 +61,17 @@
61
61
  34. [Track and Measure User Aha Moment](#track-and-measure-user-aha-moment)
62
62
  35. [Track Subscription Revenue & Build Daily Subscription Dashboard](#track-subscription-revenue--build-daily-subscription-dashboard)
63
63
 
64
- ### Initial Setup (4)
65
- 36. [Shiplens CLI One-Click Setup & Analytics Initialization](#shiplens-cli-one-click-setup--analytics-initialization)
66
- 37. [Remove Shiplens SDK & Analytics Data](#remove-shiplens-sdk--analytics-data)
67
- 38. [Uninstall Shiplens CLI](#uninstall-shiplens-cli)
68
- 39. [Generate Context Descriptions for All Pages and Buttons](#generate-context-descriptions-for-all-pages-and-buttons)
64
+ ### Initial Setup (5)
65
+ 36. [Shiplens CLI One-Click Setup & Analytics Initialization](#shiplens-cli-one-click-setup-analytics-initialization)
66
+ 37. [Use Shiplens CLI to Install Analytics SDK & Link to Existing Account](#use-shiplens-cli-to-install-analytics-sdk-link-to-existing-account)
67
+ 38. [Delete Shiplens Project Analytics Data & SDK (No Longer Needed)](#delete-shiplens-project-analytics-data-sdk-no-longer-needed)
68
+ 39. [Delete Shiplens CLI](#delete-shiplens-cli)
69
+ 40. [Use Shiplens CLI to Generate Context Descriptions for All Pages and Buttons](#use-shiplens-cli-to-generate-context-descriptions-for-all-pages-and-buttons)
69
70
 
70
71
  ### Troubleshooting & Diagnostics (3)
71
- 40. [Test Shiplens Telemetry Pipeline and Environment](#test-shiplens-telemetry-pipeline-and-environment)
72
- 41. [Enable Local Debug Mode and Verify Event Reporting](#enable-local-debug-mode-and-verify-event-reporting)
73
- 42. [Test Event Reporting in Production Build & Release Environments](#test-event-reporting-in-production-build--release-environments)
72
+ 41. [Test Shiplens Telemetry Pipeline and Environment](#test-shiplens-telemetry-pipeline-and-environment)
73
+ 42. [Enable Local Debug Mode and Verify Event Reporting](#enable-local-debug-mode-and-verify-event-reporting)
74
+ 43. [Test Event Reporting in Production Build & Release Environments](#test-event-reporting-in-production-build--release-environments)
74
75
 
75
76
  ---
76
77
 
@@ -734,18 +735,44 @@ Sources:
734
735
 
735
736
  #### [setup_init] Shiplens CLI One-Click Setup & Analytics Initialization (Suffix: None)
736
737
  ```text
737
- Set up Shiplens analytics: extract project description, install SDK, create the project, and retrieve the live dashboard URL.
738
+ Set up Shiplens analytics: install SDK, create the project, and retrieve the live dashboard URL.
738
739
  1. Run CLI initialization command:
739
- - Windows: npx.cmd --yes @shiplens/cli init
740
- - macOS/Linux: npx --yes @shiplens/cli init
740
+ - Windows: npx.cmd --yes @shiplens/cli init --json
741
+ - macOS/Linux: npx --yes @shiplens/cli init --json
741
742
  2. Present the standard project & dashboard summary (including: Project Name, App ID, Code Injection file, User Account Status, Live Dashboard / Activation URL);
742
743
  3. Immediately prompt the user for their email address (informing them that you will register on their behalf and Shiplens will send an activation email for 50,000 monthly free events and project binding);
743
744
  4. Upon receiving the user's email, run: npx.cmd --yes @shiplens/cli auth bind --email <email> --json.
744
745
  ```
745
746
 
746
- #### [remove_sdk] Remove Shiplens SDK & Analytics Data (Suffix: None)
747
+ #### [setup_bind_project] Use Shiplens CLI to Install Analytics SDK & Link to Existing Account (Suffix: None)
747
748
  ```text
748
- Remove Shiplens SDK integration and analytics data:
749
+ Use Shiplens CLI to install the analytics SDK in this new project and link it to the user's existing Shiplens account:
750
+
751
+ 1. Run the project setup & initialization command:
752
+ - Windows: npx.cmd --yes @shiplens/cli init --json
753
+ - macOS/Linux: npx --yes @shiplens/cli init --json
754
+ (Automatically detects framework, installs SDK dependency, injects code entry, and creates cloud project)
755
+
756
+ 2. Inspect returned `user_account_status` and credential states:
757
+ - [Branch A: Logged in & linked] (`logged_in_linked`):
758
+ No extra step needed; present the project summary card containing App ID, Project Name, Injected file, and Live Dashboard URL (`dashboard_url`).
759
+ - [Branch B: No local credentials detected] (`not_logged_in_unlinked` or `activation_required=true`):
760
+ Prompt the user for their registered Shiplens account email, and upon reply run:
761
+ `npx.cmd --yes @shiplens/cli auth bind --email <email> --json`
762
+ Instruct the user to click the Magic Link in the email to authorize and complete project binding.
763
+ - [Branch C: Account quota / project limit reached] (Error `QUOTA_EXCEEDED` / `PLAN_LIMIT` / unable to link):
764
+ Clearly notify the user that their current free/existing tier project limit or monthly event quota is full;
765
+ Provide upgrade instructions: recommend upgrading to Pro / Team tier (URL: https://shiplens.dev/pricing or console settings) for expanded project limits and advanced analytics;
766
+ Note that once upgraded, re-running the bind command will activate immediately without modifying code.
767
+
768
+ 3. Output the final project summary and dashboard link, confirming the project is ready for analytics queries.
769
+
770
+ Please prioritize calling Shiplens CLI (Action: setup_bind_project) to execute the above requirements.
771
+ ```
772
+
773
+ #### [remove_sdk] Delete Shiplens Project Analytics Data & SDK (No Longer Needed) (Suffix: None)
774
+ ```text
775
+ Delete Shiplens project analytics data and SDK integration (analytics no longer needed):
749
776
  1. Read `.shiplens.json` in the project root to get project name, app_id, and instrumented file paths.
750
777
  2. Clearly display the project name and app_id to be deleted, warn the user that historical events and hosted data will be permanently purged, and pause for explicit user confirmation ("Confirm deleting this project").
751
778
  3. Upon confirmation, remove SDK imports/instrumentation code from local frontend files, and delete `./.shiplens.json` and `.shiplens/contexts/<app_id>.md`.
@@ -754,16 +781,16 @@ Remove Shiplens SDK integration and analytics data:
754
781
  Please prioritize calling Shiplens CLI (Action: remove_sdk) to execute the above requirements.
755
782
  ```
756
783
 
757
- #### [uninstall_cli] Uninstall Shiplens CLI (Suffix: None)
784
+ #### [uninstall_cli] Delete Shiplens CLI (Suffix: None)
758
785
  ```text
759
786
  Please prioritize calling Shiplens CLI (Action: uninstall_cli) to execute the above requirements.
760
787
  - Windows: npm.cmd uninstall -g @shiplens/cli
761
788
  - macOS/Linux: npm uninstall -g @shiplens/cli
762
789
  ```
763
790
 
764
- #### [generate_context] Generate Context Descriptions for All Pages and Buttons (Suffix: None)
791
+ #### [generate_context] Use Shiplens CLI to Generate Context Descriptions for All Pages and Buttons (Suffix: None)
765
792
  ```text
766
- Map pages, features, and button layouts into `.shiplens/contexts/<app_id>.md` so AI analytics can map numbers and IDs to concrete functionality:
793
+ Use Shiplens CLI to map pages, features, and button layouts into `.shiplens/contexts/<app_id>.md` so AI analytics can understand the business context behind each metric:
767
794
  1. Check `./.shiplens.json` for current app_id and project name.
768
795
  2. Inspect frontend code and routes to extract feature descriptions, user-facing copy, and button texts, locations, and actions.
769
796
  3. Write structured details into `.shiplens/contexts/<app_id>.md`, binding app_id and project name in the header.