@shiplens/cli 1.4.2 → 1.4.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 +30 -30
- package/docs/02_CLI_COMMAND_REFERENCE.md +204 -0
- package/lib/api.js +35 -55
- package/lib/assets/actions.json +754 -0
- package/lib/assets/skill.js +137 -140
- package/lib/cli.js +64 -55
- package/lib/commands/action.js +112 -0
- package/lib/commands/auth.js +36 -41
- package/lib/commands/context.js +13 -18
- package/lib/commands/dashboards.js +16 -24
- package/lib/commands/doctor.js +43 -34
- package/lib/commands/heatmap.js +14 -9
- package/lib/commands/init.js +51 -51
- package/lib/commands/mcp.js +2 -2
- package/lib/commands/pages.js +19 -23
- package/lib/commands/projects.js +13 -13
- package/lib/commands/query.js +10 -12
- package/lib/commands/sql.js +4 -5
- package/lib/commands/summary.js +7 -7
- package/lib/injector.js +19 -22
- package/lib/mcp-config.js +5 -5
- package/lib/taxonomy.js +22 -25
- package/package.json +6 -3
- package/prompts/README.md +2 -3
- package/prompts/prompts_cli_en-US.md +821 -0
- package/docs/02_SHIPLENS_CLI_/345/205/250/345/221/275/344/273/244/345/217/202/350/200/203/346/211/213/345/206/214.md +0 -205
- package/prompts/prompts_cli_zh.md +0 -743
package/lib/assets/skill.js
CHANGED
|
@@ -1,204 +1,201 @@
|
|
|
1
1
|
const SKILL_CONTENT = `---
|
|
2
2
|
name: shiplens-analytics
|
|
3
|
-
description: Shiplens Web
|
|
3
|
+
description: Shiplens Web Analytics — Agent behavior protocol, diagnostics, and data analysis execution.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
|
-
# Shiplens Web
|
|
6
|
+
# Shiplens Web Analytics Skill (v3.1)
|
|
7
7
|
|
|
8
|
-
Shiplens
|
|
8
|
+
Shiplens provides web user behavior analytics via CLI and MCP. This document defines how an AI Agent should diagnose, onboard, and analyze data for any project using Shiplens.
|
|
9
9
|
|
|
10
10
|
---
|
|
11
11
|
|
|
12
|
-
## 1.
|
|
12
|
+
## 1. Environment Diagnostics
|
|
13
13
|
|
|
14
|
-
|
|
14
|
+
Before executing any command, check three signals to determine project state:
|
|
15
15
|
|
|
16
|
-
|
|
|
17
|
-
|
|
18
|
-
|
|
|
19
|
-
| **SDK** | \`package.json\`
|
|
20
|
-
|
|
|
16
|
+
| Signal | What to check |
|
|
17
|
+
|--------|---------------|
|
|
18
|
+
| **Auth** | Does \`shiplens.env\` or env var \`SHIPLENS_ACCESS_SECRET\` exist? |
|
|
19
|
+
| **SDK** | Is \`@shiplens/sdk\` in \`package.json\` and instrumented in source? |
|
|
20
|
+
| **Cloud** | Does \`.shiplens.json\` contain a valid \`app_id\`? |
|
|
21
21
|
|
|
22
|
-
###
|
|
22
|
+
### State Matrix
|
|
23
23
|
|
|
24
|
-
|
|
|
25
|
-
|
|
26
|
-
|
|
|
27
|
-
|
|
|
28
|
-
|
|
|
29
|
-
|
|
|
24
|
+
| State | Condition | Action |
|
|
25
|
+
|-------|-----------|--------|
|
|
26
|
+
| **A — Ready** | All three ✓ | Proceed to data analysis (§3) |
|
|
27
|
+
| **A-1 — No project** | Auth ✓, no \`app_id\` | User authenticated, but cloud account has no projects or project is not linked. Guide user to \`shiplens.dev\` to verify account or create a project |
|
|
28
|
+
| **B — No auth / New device** | SDK ✓, Auth ✗ | Missing local \`shiplens.env\`. Ask: *"Have you registered a Shiplens account?"*<br>• **Registered**: Guide user to visit \`https://shiplens.dev/settings/api-keys\`, download the \`shiplens.env\` file and place it in the project root (advanced users can copy the API key and run \`shiplens auth set --secret <key>\`).<br>• **Not registered**: Ask for email and run \`shiplens auth bind --email <email> --json\`. |
|
|
29
|
+
| **C — Cold start** | SDK ✗, Auth ✗ | Run \`shiplens init\` (§2) |
|
|
30
30
|
|
|
31
|
-
|
|
31
|
+
This matrix doubles as the troubleshooting baseline. When anything breaks, trace back through these three signals.
|
|
32
32
|
|
|
33
33
|
---
|
|
34
34
|
|
|
35
|
-
## 2.
|
|
35
|
+
## 2. Project Onboarding
|
|
36
36
|
|
|
37
|
-
###
|
|
37
|
+
### Run
|
|
38
38
|
\`\`\`bash
|
|
39
|
-
npx.cmd --yes @shiplens/cli init --json # Windows
|
|
39
|
+
npx.cmd --yes @shiplens/cli init --json # Windows PowerShell
|
|
40
40
|
npx --yes @shiplens/cli init --json # macOS / Linux
|
|
41
41
|
\`\`\`
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
###
|
|
45
|
-
1.
|
|
46
|
-
2.
|
|
47
|
-
3.
|
|
48
|
-
4.
|
|
49
|
-
5.
|
|
50
|
-
6.
|
|
51
|
-
7.
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
- **零后续摩擦**:本地 Agent **无需执行额外的登录命令或索要 Token**,已写入的 \`shiplens.env\` 即刻生效,后续的数据查询(\`shiplens query\`)与 MCP 服务(\`shiplens mcp serve\`)直接可用。
|
|
68
|
-
|
|
69
|
-
### 汇报模板
|
|
70
|
-
初始化完成后,输出标准卡片:
|
|
42
|
+
Backup mirror fallback: add \`--registry=https://registry.npmmirror.com\`
|
|
43
|
+
|
|
44
|
+
### What init does (~15 seconds, one atomic command)
|
|
45
|
+
1. Detect framework (Next.js / Vite / Vue / HTML)
|
|
46
|
+
2. Install \`@shiplens/sdk\`
|
|
47
|
+
3. Inject tracking code into entry file
|
|
48
|
+
4. Register project via \`POST /api/connect\` → receive \`app_id\` + \`dashboard_url\`
|
|
49
|
+
5. Scan page content → generate \`.shiplens/contexts/<app_id>.md\`
|
|
50
|
+
6. Write local state machine \`.shiplens.json\`
|
|
51
|
+
7. Inject this AI Skill file and Agent rules
|
|
52
|
+
|
|
53
|
+
### Overwrite Protection & Comparison
|
|
54
|
+
If \`.shiplens.json\` or SDK instrumentation already exists, **stop and present the clear comparison**:
|
|
55
|
+
- **Option 1 [Recommended]**: Keep existing statistics. Retain existing project ID and historical data, new traffic continues accumulating on current dashboard.
|
|
56
|
+
- **Option 2 [Overwrite]**: Overwrite with \`--force\`. Request a brand new blank project ID from cloud and overwrite local code (**Note**: Old dashboard will stop receiving new data, old and new data cannot be merged).
|
|
57
|
+
|
|
58
|
+
### Post-Init: Request Email & Seamless Activation
|
|
59
|
+
When \`shiplens auth bind --email <email> --json\` is called:
|
|
60
|
+
1. Server generates device credentials and writes them directly to local \`shiplens.env\` (0600 permissions, auto-gitignored).
|
|
61
|
+
2. Server sends a Magic Link email to the user.
|
|
62
|
+
3. Once the user clicks the email link, the cloud account and device credentials become active immediately.
|
|
63
|
+
4. **Zero extra steps for Agent**: Future queries and \`shiplens mcp serve\` will authenticate automatically without manual login.
|
|
64
|
+
|
|
65
|
+
### Reporting Template
|
|
66
|
+
After init, present:
|
|
71
67
|
|
|
72
68
|
\`\`\`markdown
|
|
73
|
-
### 📊
|
|
74
|
-
-
|
|
75
|
-
-
|
|
76
|
-
-
|
|
77
|
-
-
|
|
78
|
-
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
>
|
|
82
|
-
> **请告诉我您的邮箱**:点击邮件中的链接即可完成注册,激活每月 50,000 事件的免费额度(约5000人访问),同时绑定项目和账号;激活后您与我直接对话,我就有权限查询并分析产品数据。
|
|
69
|
+
### 📊 Project & Analytics Information
|
|
70
|
+
- **Project Name**: \\\`<project_name>\\\`
|
|
71
|
+
- **App ID**: \\\`<app_id>\\\`
|
|
72
|
+
- **Code Injection**: [\\\`<injected_file>\\\`](file:///<path>)
|
|
73
|
+
- **Live Dashboard**: [<dashboard_url>](<dashboard_url>)
|
|
74
|
+
- **Account Status**: <status>
|
|
75
|
+
- **AI Skill**: [\\\`.agents/skills/shiplens/SKILL.md\\\`](file:///<path>)
|
|
76
|
+
|
|
77
|
+
> **Activate your project**: Share your email to activate monthly free event quota and link your project with your account.
|
|
83
78
|
\`\`\`
|
|
84
79
|
|
|
85
|
-
|
|
86
|
-
-
|
|
87
|
-
-
|
|
88
|
-
-
|
|
80
|
+
Account status values:
|
|
81
|
+
- \`Logged in (project linked)\` — credentials exist, project bound
|
|
82
|
+
- \`Logged in (project not linked)\` — credentials exist, project unbound
|
|
83
|
+
- \`Not logged in (Default state after first installation or no valid local credentials)\`
|
|
89
84
|
|
|
90
85
|
---
|
|
91
86
|
|
|
92
|
-
## 3.
|
|
93
|
-
|
|
94
|
-
当用户提出任何独立的数据分析需求时:
|
|
87
|
+
## 3. Data Analysis Protocol (6 Steps)
|
|
95
88
|
|
|
96
|
-
|
|
89
|
+
When processing any analytics or telemetry request:
|
|
97
90
|
|
|
98
|
-
|
|
91
|
+
**Step 1 — Read Learnings**: Check \`.shiplens/learnings.md\` for project overrides (date range, metrics, cohort intervals).
|
|
99
92
|
|
|
100
|
-
|
|
93
|
+
**Step 2 — Read Context**: Read \`.shiplens/contexts/<app_id>.md\` (or run \`shiplens context show --json\`) to ground numbers in real page routes and button labels.
|
|
101
94
|
|
|
102
|
-
|
|
95
|
+
**Step 3 — Route Execution Path (Tri-Route Decision)**:
|
|
96
|
+
- **Route A (Exact Action ID)**: If input contains an \`action_id\` (e.g. \`lifecycle_stage\` or \`Action: <id>\`), run \`shiplens action <id> --json\` to retrieve prescribed steps and commands.
|
|
97
|
+
- **Route B (Scenario Preset Match)**: If input is natural language matching one of the 42 textbook growth/retention scenarios, run \`shiplens action <id> --json\` for that scenario.
|
|
98
|
+
- **Route C (Ad-Hoc Autonomous Composition)**: If input is a custom, open-ended question without a preset action, autonomously select and compose CLI commands from the Atomic Toolset (§4) to query required metrics.
|
|
103
99
|
|
|
104
|
-
|
|
100
|
+
**Step 4 — Execute**: Run selected CLI commands with Step 1 overrides applied. Always include \`--json\`.
|
|
105
101
|
|
|
106
|
-
|
|
102
|
+
**Step 5 — Synthesize**: Translate numbers into concrete business conclusions, metric benchmarks, and actionable next steps using UI terminology from Step 2.
|
|
107
103
|
|
|
108
|
-
|
|
109
|
-
- **优先级 1**:\`.shiplens/learnings.md\` — 项目专属用户动态偏好(场景细分覆盖 > 全局通用偏好)
|
|
110
|
-
- **优先级 2**:\`prompts/prompts_cli_zh.md\` — 42 个教科书经典分析场景底座
|
|
104
|
+
**Step 6 — Record**: If user clarifies or corrects preferences (e.g., "always use 14d for cohort retention"), ask to persist to \`.shiplens/learnings.md\` (§6).
|
|
111
105
|
|
|
112
106
|
---
|
|
113
107
|
|
|
114
|
-
## 4.
|
|
115
|
-
|
|
116
|
-
|
|
|
117
|
-
|
|
118
|
-
| \`shiplens
|
|
119
|
-
| \`shiplens
|
|
120
|
-
| \`shiplens
|
|
121
|
-
| \`shiplens
|
|
122
|
-
| \`shiplens
|
|
123
|
-
| \`shiplens
|
|
124
|
-
| \`shiplens
|
|
125
|
-
| \`shiplens
|
|
126
|
-
| \`shiplens
|
|
127
|
-
| \`shiplens context
|
|
128
|
-
| \`shiplens auth bind --email
|
|
129
|
-
| \`shiplens
|
|
130
|
-
| \`shiplens
|
|
131
|
-
| \`shiplens projects delete --app-id <id> --json\` | 删除项目(**高危操作,必须二次确认**,§5) |
|
|
108
|
+
## 4. Atomic CLI Toolset & Composition Matrix
|
|
109
|
+
|
|
110
|
+
| Command | Capability | Typical Scenarios & Composition |
|
|
111
|
+
|---------|------------|---------------------------------|
|
|
112
|
+
| \`shiplens summary --range 7d --json\` | Macro Overview | Total UV, PV, bounce rates, top geos, device distribution |
|
|
113
|
+
| \`shiplens query --metric <m> --range 7d --json\` | Multidimensional Metrics | Retention matrix (\`daily_retention\`), funnels (\`conversion_funnel\`), pageview trends |
|
|
114
|
+
| \`shiplens pages --range 7d --json\` | Page Performance | Route visit counts, average dwell time, high-traffic pages |
|
|
115
|
+
| \`shiplens paths --range 7d --json\` | User Journeys | Entry-to-exit flow, drop-off routes, navigation transitions |
|
|
116
|
+
| \`shiplens heatmap --template <id> --json\` | UI & Click Patterns | Button click distributions, wireframe skeleton click rates |
|
|
117
|
+
| \`shiplens sql --query "<sql>" --json\` | Custom Slicing | Multi-filter joins, power user segmentation, ad-hoc event queries |
|
|
118
|
+
| \`shiplens dashboards create --title "..." --prompt "..." --json\` | Dashboard Creation | AI-generated 12-column live dashboards |
|
|
119
|
+
| \`shiplens action [id] [--list] --json\` | Action Presets | 42 textbook scenario steps, commands, and theory |
|
|
120
|
+
| \`shiplens doctor --json\` | Diagnostics | Diagnose config, SDK, network, credentials |
|
|
121
|
+
| \`shiplens context show --json\` | Business Context | Inspect mapped page routes and UI button semantics |
|
|
122
|
+
| \`shiplens auth bind --email <email> --json\` | Activation | Send Magic Link email for project binding |
|
|
123
|
+
| \`shiplens mcp serve\` | MCP Server | Start local stdio MCP proxy for IDE/Agent |
|
|
124
|
+
| \`shiplens projects delete --app-id <id> --json\` | Deletion | Delete project (**requires confirmation**, §5) |
|
|
132
125
|
|
|
133
126
|
---
|
|
134
127
|
|
|
135
|
-
## 5.
|
|
128
|
+
## 5. Safety Rules
|
|
136
129
|
|
|
137
|
-
###
|
|
138
|
-
|
|
139
|
-
1.
|
|
140
|
-
2.
|
|
141
|
-
3.
|
|
142
|
-
4.
|
|
130
|
+
### Project Deletion — Stop and Confirm (HITL)
|
|
131
|
+
Before deleting any project:
|
|
132
|
+
1. Show project name, \`app_id\`, and creation date.
|
|
133
|
+
2. Warn: *"This permanently deletes all data, dashboards, and config. Cannot be undone."*
|
|
134
|
+
3. Explicitly pause and wait for user to reply "confirm delete".
|
|
135
|
+
4. Only then execute \`shiplens projects delete\`.
|
|
143
136
|
|
|
144
|
-
|
|
137
|
+
Never skip this step.
|
|
145
138
|
|
|
146
|
-
### SQL
|
|
147
|
-
-
|
|
148
|
-
-
|
|
149
|
-
-
|
|
139
|
+
### SQL
|
|
140
|
+
- Always \`WHERE timestamp >= now() - INTERVAL <N> DAY\`
|
|
141
|
+
- Always \`LIMIT\` (max 1000)
|
|
142
|
+
- Table: \`events\` (read-only ClickHouse)
|
|
150
143
|
|
|
151
|
-
### Windows
|
|
152
|
-
-
|
|
153
|
-
-
|
|
144
|
+
### Windows Execution Policy
|
|
145
|
+
- Use \`.cmd\` suffix: \`npx.cmd\`, \`npm.cmd\`
|
|
146
|
+
- Chain commands with \`;\` not \`&&\`
|
|
154
147
|
|
|
155
148
|
---
|
|
156
149
|
|
|
157
|
-
## 6.
|
|
150
|
+
## 6. Adaptive Learning (\`.shiplens/learnings.md\`)
|
|
158
151
|
|
|
159
|
-
|
|
152
|
+
Stores user preferences that override defaults. Understand the specific scenario scope (e.g. retention vs. funnel vs. channels) instead of applying narrow rules globally.
|
|
160
153
|
|
|
161
|
-
###
|
|
154
|
+
### Format
|
|
162
155
|
\`\`\`markdown
|
|
163
|
-
# Shiplens
|
|
156
|
+
# Shiplens Project Learnings
|
|
157
|
+
|
|
158
|
+
## Global Overrides
|
|
159
|
+
- default_range: 30d
|
|
160
|
+
- exclude_filter: user_id NOT IN ('test_1', 'test_2')
|
|
164
161
|
|
|
165
|
-
##
|
|
166
|
-
|
|
167
|
-
-
|
|
162
|
+
## Scenario-Specific Overrides
|
|
163
|
+
### Retention Analysis
|
|
164
|
+
- cohort_interval: 14d
|
|
165
|
+
- retention_benchmark: day_1_day_7_day_30
|
|
168
166
|
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
- default_range: 14d # 用户偏好以双周周期评估留存衰减
|
|
172
|
-
- focus_metrics: ["第 14 天留存率", "次周回访率"]
|
|
167
|
+
### Conversion Funnel
|
|
168
|
+
- primary_conversion_goal: /signup → /onboarding → /dashboard
|
|
173
169
|
|
|
174
|
-
###
|
|
175
|
-
-
|
|
176
|
-
-
|
|
170
|
+
### Custom Analysis Habits
|
|
171
|
+
- Always show week-over-week comparison
|
|
172
|
+
- Report bounce rate per page, not aggregate
|
|
177
173
|
\`\`\`
|
|
178
174
|
|
|
179
|
-
###
|
|
180
|
-
-
|
|
181
|
-
-
|
|
182
|
-
-
|
|
175
|
+
### Rules
|
|
176
|
+
- Do **not** create during \`init\`
|
|
177
|
+
- Create on first user-confirmed preference save
|
|
178
|
+
- Scope preferences accurately to avoid inappropriate global overrides
|
|
179
|
+
- Always ask before writing
|
|
183
180
|
|
|
184
181
|
---
|
|
185
182
|
|
|
186
|
-
## 7.
|
|
183
|
+
## 7. SQL Reference
|
|
187
184
|
|
|
188
|
-
|
|
185
|
+
**Table**: \`events\` (ClickHouse, read-only)
|
|
189
186
|
|
|
190
|
-
|
|
|
191
|
-
|
|
192
|
-
| \`timestamp\` | DateTime |
|
|
187
|
+
| Column | Type | Description |
|
|
188
|
+
|--------|------|-------------|
|
|
189
|
+
| \`timestamp\` | DateTime | Event time |
|
|
193
190
|
| \`event_name\` | String | pageview, click, custom |
|
|
194
|
-
| \`user_id\` | String |
|
|
195
|
-
| \`session_id\` | String |
|
|
196
|
-
| \`template_id\` | String | DOM
|
|
197
|
-
| \`page_path\` | String |
|
|
198
|
-
| \`referrer\` | String |
|
|
199
|
-
| \`properties\` | Map(String, String) |
|
|
200
|
-
|
|
201
|
-
ClickHouse
|
|
191
|
+
| \`user_id\` | String | User ID |
|
|
192
|
+
| \`session_id\` | String | Session ID |
|
|
193
|
+
| \`template_id\` | String | DOM hash (page template) |
|
|
194
|
+
| \`page_path\` | String | URL path |
|
|
195
|
+
| \`referrer\` | String | Referrer URL |
|
|
196
|
+
| \`properties\` | Map(String, String) | Custom event data |
|
|
197
|
+
|
|
198
|
+
ClickHouse functions: \`countIf()\`, \`quantile(0.50)()\`, \`dateDiff()\`, \`uniq()\`.
|
|
202
199
|
`;
|
|
203
200
|
|
|
204
201
|
module.exports = { SKILL_CONTENT };
|
package/lib/cli.js
CHANGED
|
@@ -14,8 +14,13 @@ const { handleDashboards } = require('./commands/dashboards');
|
|
|
14
14
|
const { handleDoctor } = require('./commands/doctor');
|
|
15
15
|
const { handleContext } = require('./commands/context');
|
|
16
16
|
const { handleMcp } = require('./commands/mcp');
|
|
17
|
+
const { handleAction } = require('./commands/action');
|
|
17
18
|
|
|
18
|
-
|
|
19
|
+
let VERSION = '1.4.4';
|
|
20
|
+
try {
|
|
21
|
+
const pkg = require('../package.json');
|
|
22
|
+
if (pkg.version) VERSION = pkg.version;
|
|
23
|
+
} catch (e) {}
|
|
19
24
|
|
|
20
25
|
function parseArgs(argv) {
|
|
21
26
|
const flags = {};
|
|
@@ -65,61 +70,62 @@ function parseArgs(argv) {
|
|
|
65
70
|
}
|
|
66
71
|
|
|
67
72
|
function printHelp() {
|
|
68
|
-
console.log(`Shiplens CLI
|
|
73
|
+
console.log(`Shiplens CLI - High-Speed User Telemetry & SDK Management Tool (v${VERSION})
|
|
69
74
|
|
|
70
|
-
|
|
71
|
-
shiplens
|
|
72
|
-
npx.cmd --yes shiplens-cli
|
|
73
|
-
npx --yes shiplens-cli
|
|
75
|
+
Usage:
|
|
76
|
+
shiplens <command> [subcommand] [options]
|
|
77
|
+
npx.cmd --yes shiplens-cli <command> [subcommand] [options] (Windows)
|
|
78
|
+
npx --yes shiplens-cli <command> [subcommand] [options] (macOS/Linux)
|
|
74
79
|
|
|
75
|
-
|
|
76
|
-
init
|
|
77
|
-
auth
|
|
78
|
-
projects
|
|
79
|
-
query
|
|
80
|
-
sql
|
|
81
|
-
summary
|
|
82
|
-
pages
|
|
83
|
-
paths
|
|
84
|
-
canvas
|
|
85
|
-
heatmap
|
|
86
|
-
dashboards AI
|
|
87
|
-
doctor
|
|
88
|
-
context
|
|
89
|
-
|
|
80
|
+
Core Commands:
|
|
81
|
+
init 15-second zero-config analytics initialization & dashboard setup
|
|
82
|
+
auth Authentication & credentials (status, set, secret, whoami, logout, bind, mcp-config, configure)
|
|
83
|
+
projects Project management (list, bind, delete)
|
|
84
|
+
query Multi-dimensional metrics and conversion funnel queries
|
|
85
|
+
sql Execute secure read-only SQL queries on ClickHouse
|
|
86
|
+
summary Retrieve product overview (traffic, bounce rates, geos, devices)
|
|
87
|
+
pages Inspect page-level visits and average dwell times
|
|
88
|
+
paths Analyze user flow journeys and Sankey transition paths
|
|
89
|
+
canvas Retrieve global user behavior canvas topology
|
|
90
|
+
heatmap Retrieve click heatmaps and skeleton wireframes
|
|
91
|
+
dashboards AI dashboard management and one-click creation (list, create [--ai])
|
|
92
|
+
doctor Run full end-to-end diagnostics on SDK, credentials, and network
|
|
93
|
+
context Manage business context dictionary (push, pull, show)
|
|
94
|
+
action Retrieve deterministic steps, commands, and theory for analysis actions (list, <action_id>)
|
|
95
|
+
mcp serve Run local MCP proxy server with device credentials
|
|
90
96
|
|
|
91
|
-
auth
|
|
92
|
-
auth status
|
|
93
|
-
auth set [--secret-stdin]
|
|
94
|
-
auth secret list
|
|
95
|
-
auth secret create [--scopes ...]
|
|
96
|
-
auth secret revoke --key-id <id>
|
|
97
|
-
auth whoami
|
|
98
|
-
auth logout
|
|
99
|
-
auth bind --email
|
|
100
|
-
auth mcp-config [--client <client>]
|
|
101
|
-
auth configure --client <client>
|
|
102
|
-
auth configure --client manual
|
|
97
|
+
auth Subcommands:
|
|
98
|
+
auth status Check credential validity
|
|
99
|
+
auth set [--secret-stdin] Save Access Secret
|
|
100
|
+
auth secret list List Access Secrets (masked)
|
|
101
|
+
auth secret create [--scopes ...] Create scoped offline Access Secret
|
|
102
|
+
auth secret revoke --key-id <id> Revoke offline Access Secret
|
|
103
|
+
auth whoami Display current authenticated user
|
|
104
|
+
auth logout Clear local credentials
|
|
105
|
+
auth bind --email <email> [--json] Send Magic Link email for account binding
|
|
106
|
+
auth mcp-config [--client <client>] Print MCP configuration (cursor/codex/claude/antigravity/manual)
|
|
107
|
+
auth configure --client <client> Write MCP configuration into target client
|
|
108
|
+
auth configure --client manual Output standard MCP JSON configuration
|
|
103
109
|
|
|
104
|
-
init
|
|
105
|
-
--name <string>
|
|
106
|
-
--description <string>
|
|
107
|
-
--genre <id> Level 1
|
|
108
|
-
--subgenre <id> Level 2
|
|
109
|
-
--tags <ids> Level 4
|
|
110
|
-
--industry <string>
|
|
111
|
-
--email <email|auto>
|
|
110
|
+
init Dedicated Options:
|
|
111
|
+
--name <string> Project name (default: auto-read from package.json)
|
|
112
|
+
--description <string> Project functional description & positioning
|
|
113
|
+
--genre <id> Level 1 category ID (e.g. utilities, finance, casual_games)
|
|
114
|
+
--subgenre <id> Level 2 subcategory ID (e.g. developer_tools, financial_tools)
|
|
115
|
+
--tags <ids> Level 4 feature tags (comma-separated tag_ids)
|
|
116
|
+
--industry <string> Compatibility industry category field
|
|
117
|
+
--email <email|auto> Auto or manual binding email
|
|
112
118
|
|
|
113
|
-
|
|
114
|
-
--json
|
|
115
|
-
--force
|
|
116
|
-
--no-commit
|
|
117
|
-
--app-id <id>
|
|
118
|
-
--env <env>
|
|
119
|
-
--secret <key>
|
|
120
|
-
--api-url <url>
|
|
121
|
-
-v, --version
|
|
122
|
-
-h, --help
|
|
119
|
+
Global Options:
|
|
120
|
+
--json Output in standard JSON format (required for AI Agents)
|
|
121
|
+
--force Force overwrite existing local configuration and project ID
|
|
122
|
+
--no-commit Skip automatic Git commit after initialization
|
|
123
|
+
--app-id <id> Explicitly specify target project app_id
|
|
124
|
+
--env <env> Target environment (production / staging, default: production)
|
|
125
|
+
--secret <key> Pass Access Secret explicitly
|
|
126
|
+
--api-url <url> Custom backend API base URL (default: http://120.26.230.33)
|
|
127
|
+
-v, --version Display CLI version
|
|
128
|
+
-h, --help Display help information
|
|
123
129
|
`);
|
|
124
130
|
}
|
|
125
131
|
|
|
@@ -162,12 +168,12 @@ async function runCLI(argv = process.argv.slice(2)) {
|
|
|
162
168
|
status: err.status,
|
|
163
169
|
}, null, 2));
|
|
164
170
|
} else {
|
|
165
|
-
console.error(`❌
|
|
171
|
+
console.error(`❌ Error [${code}]: ${err.message}`);
|
|
166
172
|
}
|
|
167
173
|
process.exitCode = 1;
|
|
168
174
|
};
|
|
169
175
|
|
|
170
|
-
//
|
|
176
|
+
// Resolve credentials and API client
|
|
171
177
|
const resolvedAuth = resolveSecret(flags.secret);
|
|
172
178
|
let apiUrl = flags['api-url'] || process.env.SHIPLENS_API_URL;
|
|
173
179
|
if (!apiUrl) {
|
|
@@ -182,7 +188,7 @@ async function runCLI(argv = process.argv.slice(2)) {
|
|
|
182
188
|
if (flags['app-id']) return flags['app-id'];
|
|
183
189
|
const localCfg = getLocalConfig();
|
|
184
190
|
if (localCfg && localCfg.app_id) return localCfg.app_id;
|
|
185
|
-
const err = new Error('
|
|
191
|
+
const err = new Error('Target app_id not found. Provide --app-id or run inside an initialized project directory.');
|
|
186
192
|
err.code = 'APP_NOT_FOUND';
|
|
187
193
|
throw err;
|
|
188
194
|
};
|
|
@@ -240,11 +246,14 @@ async function runCLI(argv = process.argv.slice(2)) {
|
|
|
240
246
|
case 'context':
|
|
241
247
|
await handleContext(subcommand || 'show', args.slice(2), flags, ctx);
|
|
242
248
|
break;
|
|
249
|
+
case 'action':
|
|
250
|
+
await handleAction(cmdArgs, flags, ctx);
|
|
251
|
+
break;
|
|
243
252
|
case 'mcp':
|
|
244
253
|
await handleMcp(subcommand || 'serve');
|
|
245
254
|
break;
|
|
246
255
|
default:
|
|
247
|
-
throw new Error(
|
|
256
|
+
throw new Error(`Unknown command: ${command}. Use shiplens --help to view supported commands.`);
|
|
248
257
|
}
|
|
249
258
|
} catch (err) {
|
|
250
259
|
outputError(err);
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
const path = require('path');
|
|
2
|
+
const fs = require('fs');
|
|
3
|
+
|
|
4
|
+
let actionsCache = null;
|
|
5
|
+
|
|
6
|
+
function loadActions() {
|
|
7
|
+
if (actionsCache) return actionsCache;
|
|
8
|
+
const filePath = path.join(__dirname, '..', 'assets', 'actions.json');
|
|
9
|
+
try {
|
|
10
|
+
if (fs.existsSync(filePath)) {
|
|
11
|
+
const data = JSON.parse(fs.readFileSync(filePath, 'utf8'));
|
|
12
|
+
actionsCache = data.actions || [];
|
|
13
|
+
} else {
|
|
14
|
+
actionsCache = [];
|
|
15
|
+
}
|
|
16
|
+
} catch (e) {
|
|
17
|
+
actionsCache = [];
|
|
18
|
+
}
|
|
19
|
+
return actionsCache;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
function findSimilarActions(id, allActions) {
|
|
23
|
+
const normalized = (id || '').toLowerCase().replace(/[-_\s]+/g, '');
|
|
24
|
+
return allActions
|
|
25
|
+
.filter((a) => {
|
|
26
|
+
const aNorm = a.id.toLowerCase().replace(/[-_\s]+/g, '');
|
|
27
|
+
return aNorm.includes(normalized) || normalized.includes(aNorm) || a.title.toLowerCase().includes(id.toLowerCase());
|
|
28
|
+
})
|
|
29
|
+
.slice(0, 3)
|
|
30
|
+
.map((a) => a.id);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
async function handleAction(cmdArgs, flags, ctx) {
|
|
34
|
+
const actions = loadActions();
|
|
35
|
+
const rawId = flags.id || (cmdArgs[0] && cmdArgs[0] !== 'list' ? cmdArgs[0] : null);
|
|
36
|
+
const isList = flags.list || cmdArgs[0] === 'list' || !rawId;
|
|
37
|
+
|
|
38
|
+
if (isList) {
|
|
39
|
+
const listData = {
|
|
40
|
+
ok: true,
|
|
41
|
+
total: actions.length,
|
|
42
|
+
actions: actions.map((a) => ({
|
|
43
|
+
id: a.id,
|
|
44
|
+
title: a.title,
|
|
45
|
+
category: a.category,
|
|
46
|
+
commands: a.commands,
|
|
47
|
+
})),
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
ctx.output(listData, () => {
|
|
51
|
+
console.log(`\n📋 Shiplens Action Preset Library (${actions.length} Scenarios)\n`);
|
|
52
|
+
const grouped = {};
|
|
53
|
+
for (const a of actions) {
|
|
54
|
+
if (!grouped[a.category]) grouped[a.category] = [];
|
|
55
|
+
grouped[a.category].push(a);
|
|
56
|
+
}
|
|
57
|
+
for (const [cat, items] of Object.entries(grouped)) {
|
|
58
|
+
console.log(` 📂 ${cat}:`);
|
|
59
|
+
for (const item of items) {
|
|
60
|
+
console.log(` • ${item.id.padEnd(28)} - ${item.title}`);
|
|
61
|
+
}
|
|
62
|
+
console.log('');
|
|
63
|
+
}
|
|
64
|
+
console.log('💡 Usage: shiplens action <action_id> [--json]');
|
|
65
|
+
});
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
const targetId = rawId.toLowerCase().trim();
|
|
70
|
+
const matched = actions.find((a) => a.id.toLowerCase() === targetId);
|
|
71
|
+
|
|
72
|
+
if (!matched) {
|
|
73
|
+
const suggestions = findSimilarActions(targetId, actions);
|
|
74
|
+
const err = new Error(`Action preset '${rawId}' not found.` + (suggestions.length > 0 ? ` Did you mean: ${suggestions.join(', ')}?` : ''));
|
|
75
|
+
err.code = 'ACTION_NOT_FOUND';
|
|
76
|
+
err.suggestions = suggestions;
|
|
77
|
+
throw err;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
const result = {
|
|
81
|
+
ok: true,
|
|
82
|
+
action: matched,
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
ctx.output(result, () => {
|
|
86
|
+
console.log(`\n🎯 [${matched.id}] ${matched.title}`);
|
|
87
|
+
console.log(`📂 Category: ${matched.category}`);
|
|
88
|
+
if (matched.suffix) console.log(`🏷️ Suffix: ${matched.suffix}`);
|
|
89
|
+
console.log(`\n📝 Execution Steps:`);
|
|
90
|
+
for (const s of matched.steps) {
|
|
91
|
+
console.log(` ${s}`);
|
|
92
|
+
}
|
|
93
|
+
if (matched.commands && matched.commands.length > 0) {
|
|
94
|
+
console.log(`\n⚡ Prescribed CLI Commands:`);
|
|
95
|
+
for (const c of matched.commands) {
|
|
96
|
+
console.log(` $ ${c}`);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
if (matched.foundation) {
|
|
100
|
+
console.log(`\n📚 Analysis Foundation:\n ${matched.foundation}`);
|
|
101
|
+
}
|
|
102
|
+
if (matched.source) {
|
|
103
|
+
console.log(`\n📖 Source:\n ${matched.source}`);
|
|
104
|
+
}
|
|
105
|
+
console.log('');
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
module.exports = {
|
|
110
|
+
handleAction,
|
|
111
|
+
loadActions,
|
|
112
|
+
};
|