digitalsee-ai-flow-cli 0.7.6 → 0.7.24-beta.1

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.
@@ -0,0 +1,286 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.registerServiceLogCommand = registerServiceLogCommand;
7
+ const chalk_1 = __importDefault(require("chalk"));
8
+ const service_log_1 = require("@/api/service-log");
9
+ const output_1 = require("@/utils/output");
10
+ const exit_code_1 = require("@/constants/exit-code");
11
+ const common_1 = require("@/utils/common");
12
+ const config_1 = require("@/utils/config");
13
+ const DATETIME_REGEX = /^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}$/;
14
+ function pad2(n) {
15
+ return n < 10 ? `0${n}` : String(n);
16
+ }
17
+ function formatDateTime(d) {
18
+ return (`${d.getFullYear()}-${pad2(d.getMonth() + 1)}-${pad2(d.getDate())} ` +
19
+ `${pad2(d.getHours())}:${pad2(d.getMinutes())}:${pad2(d.getSeconds())}`);
20
+ }
21
+ function colorizeLevel(level) {
22
+ const upper = (level || '').toUpperCase();
23
+ if (upper === 'ERROR' || upper === 'FATAL')
24
+ return chalk_1.default.red(level);
25
+ if (upper === 'WARN' || upper === 'WARNING')
26
+ return chalk_1.default.yellow(level);
27
+ if (upper === 'INFO')
28
+ return chalk_1.default.green(level);
29
+ if (upper === 'DEBUG' || upper === 'TRACE')
30
+ return chalk_1.default.gray(level);
31
+ return level;
32
+ }
33
+ function pickLogTime(entry) {
34
+ return entry.log_time || entry.timestamp || '-';
35
+ }
36
+ function flattenMessage(message) {
37
+ return (message ?? '').replace(/\r?\n/g, ' ');
38
+ }
39
+ function registerServiceLogCommand(program) {
40
+ const cmd = program.command('service-log').description('运维日志查询');
41
+ registerSearch(cmd);
42
+ registerStream(cmd);
43
+ }
44
+ function registerSearch(serviceLogCmd) {
45
+ serviceLogCmd
46
+ .command('search')
47
+ .description('查询历史运维日志')
48
+ .option('--time-range <r>', '相对时间范围,格式: <N>s|m|h|d(如 30s, 15m, 3h, 7d)(与 --start-time 互斥)')
49
+ .option('--start-time <time>', '开始时间 yyyy-MM-dd HH:mm:ss(与 --time-range 互斥)')
50
+ .option('--end-time <time>', '结束时间 yyyy-MM-dd HH:mm:ss(不传则服务端用请求时刻)')
51
+ .option('--limit <n>', '最大返回条数(默认 50,上限 500)', '50')
52
+ .option('--level <level>', '日志级别: INFO / WARN / ERROR')
53
+ .option('--request-id <id>', '链路 trace id(精确匹配)')
54
+ .option('--keyword <text>', '日志正文关键词')
55
+ .option('--service-type <type>', '服务类型: iam / acm / ncm / adm / mdm / nginx 等')
56
+ .option('--json', '以 JSON 输出')
57
+ .action(async (options) => {
58
+ try {
59
+ if (options.json)
60
+ (0, output_1.setJsonMode)(true);
61
+ const req = buildSearchRequest(options);
62
+ if (req instanceof Error) {
63
+ if (options.json) {
64
+ (0, output_1.printStructuredResult)({ ok: false, message: req.message });
65
+ }
66
+ else {
67
+ (0, output_1.printError)(req.message);
68
+ }
69
+ process.exitCode = exit_code_1.ExitCode.FAILURE;
70
+ return;
71
+ }
72
+ if (!options.json) {
73
+ (0, output_1.printInfo)('正在查询历史日志...');
74
+ }
75
+ const logs = await (0, service_log_1.searchServiceLogs)(req);
76
+ if (options.json) {
77
+ (0, output_1.printStructuredResult)({ ok: true, data: logs, total: logs.length });
78
+ return;
79
+ }
80
+ if (logs.length === 0) {
81
+ (0, output_1.printInfo)('暂无符合条件的日志');
82
+ return;
83
+ }
84
+ (0, output_1.printHeader)(`运维日志 (共 ${logs.length} 条,按时间倒序)`);
85
+ const rows = logs.map((entry) => [
86
+ pickLogTime(entry),
87
+ colorizeLevel(entry.level || '-'),
88
+ String(entry.host ?? '-'),
89
+ String(entry.trace_id ?? '-'),
90
+ flattenMessage(entry.message),
91
+ ]);
92
+ (0, output_1.printTable)(['时间', '级别', '服务实例', 'Trace', '消息'], rows, {
93
+ wrapCols: [4],
94
+ });
95
+ }
96
+ catch (error) {
97
+ if (options.json) {
98
+ (0, output_1.printStructuredResult)({ ok: false, message: error.message });
99
+ }
100
+ else {
101
+ (0, output_1.printError)(`查询日志失败: ${error.message}`);
102
+ }
103
+ process.exitCode = exit_code_1.ExitCode.FAILURE;
104
+ }
105
+ });
106
+ }
107
+ function buildSearchRequest(options) {
108
+ const hasRange = Boolean(options.timeRange);
109
+ const hasStart = Boolean(options.startTime);
110
+ if (!hasRange && !hasStart) {
111
+ return new Error('必须指定 --time-range 或 --start-time 之一');
112
+ }
113
+ if (hasRange && hasStart) {
114
+ return new Error('--time-range 与 --start-time 不可同时使用');
115
+ }
116
+ let start_time;
117
+ let end_time;
118
+ if (hasRange) {
119
+ const rangeKey = String(options.timeRange);
120
+ const ms = (0, common_1.parseTimeRange)(rangeKey);
121
+ if (ms === null) {
122
+ return new Error(`不支持的 --time-range 格式: "${rangeKey}",应为 <N>s|m|h|d(如 30s, 15m, 3h, 7d)`);
123
+ }
124
+ const now = new Date();
125
+ start_time = formatDateTime(new Date(now.getTime() - ms));
126
+ end_time = formatDateTime(now);
127
+ }
128
+ else {
129
+ const st = String(options.startTime);
130
+ if (!DATETIME_REGEX.test(st)) {
131
+ return new Error('--start-time 格式应为 yyyy-MM-dd HH:mm:ss');
132
+ }
133
+ start_time = st;
134
+ if (options.endTime) {
135
+ const et = String(options.endTime);
136
+ if (!DATETIME_REGEX.test(et)) {
137
+ return new Error('--end-time 格式应为 yyyy-MM-dd HH:mm:ss');
138
+ }
139
+ end_time = et;
140
+ }
141
+ }
142
+ const limit = Number(options.limit);
143
+ if (!Number.isFinite(limit) || limit <= 0) {
144
+ return new Error('--limit 必须为正整数');
145
+ }
146
+ const req = { start_time, limit };
147
+ if (end_time)
148
+ req.end_time = end_time;
149
+ if (options.level)
150
+ req.log_level = String(options.level);
151
+ if (options.requestId)
152
+ req.request_id = String(options.requestId);
153
+ if (options.keyword)
154
+ req.keyword = String(options.keyword);
155
+ if (options.serviceType)
156
+ req.service_type = String(options.serviceType);
157
+ return req;
158
+ }
159
+ function registerStream(serviceLogCmd) {
160
+ serviceLogCmd
161
+ .command('stream')
162
+ .description('实时跟随运维日志(WebSocket,Ctrl+C 退出)')
163
+ .option('--level <level>', '日志级别: INFO / WARN / ERROR')
164
+ .option('--request-id <id>', '链路 trace id(精确匹配)')
165
+ .option('--keyword <text>', '日志正文关键词')
166
+ .option('--service-type <type>', '服务类型: iam / acm / ncm / adm / mdm / nginx 等')
167
+ .option('--limit <n>', '单次 ES 拉取批量(默认 20)', '20')
168
+ .option('--max <n>', '收到 N 条后自动退出(默认不限)')
169
+ .option('--json', 'NDJSON 输出(每行一条 { ok, data })')
170
+ .action(async (options) => {
171
+ if (options.json)
172
+ (0, output_1.setJsonMode)(true);
173
+ const cfg = (0, config_1.loadConfig)();
174
+ if (!cfg.auth || !cfg.auth.access_token) {
175
+ const msg = '未登录,请先执行 ai-flow auth login';
176
+ if (options.json) {
177
+ (0, output_1.printStructuredResult)({ ok: false, message: msg });
178
+ }
179
+ else {
180
+ (0, output_1.printError)(msg);
181
+ }
182
+ process.exitCode = exit_code_1.ExitCode.FAILURE;
183
+ return;
184
+ }
185
+ try {
186
+ await (0, service_log_1.verifyToken)();
187
+ }
188
+ catch (error) {
189
+ const msg = error.message || 'Token 校验失败';
190
+ if (options.json) {
191
+ (0, output_1.printStructuredResult)({ ok: false, message: msg });
192
+ }
193
+ else {
194
+ (0, output_1.printError)(`Token 不可用: ${msg}`);
195
+ }
196
+ process.exitCode = exit_code_1.ExitCode.FAILURE;
197
+ return;
198
+ }
199
+ const filters = buildStreamFilters(options);
200
+ if (filters instanceof Error) {
201
+ if (options.json) {
202
+ (0, output_1.printStructuredResult)({ ok: false, message: filters.message });
203
+ }
204
+ else {
205
+ (0, output_1.printError)(filters.message);
206
+ }
207
+ process.exitCode = exit_code_1.ExitCode.FAILURE;
208
+ return;
209
+ }
210
+ const maxCount = options.max ? Number(options.max) : 0;
211
+ if (options.max && (!Number.isFinite(maxCount) || maxCount <= 0)) {
212
+ const msg = '--max 必须为正整数';
213
+ if (options.json) {
214
+ (0, output_1.printStructuredResult)({ ok: false, message: msg });
215
+ }
216
+ else {
217
+ (0, output_1.printError)(msg);
218
+ }
219
+ process.exitCode = exit_code_1.ExitCode.FAILURE;
220
+ return;
221
+ }
222
+ let received = 0;
223
+ let closed = false;
224
+ if (!options.json) {
225
+ (0, output_1.printInfo)('正在连接实时日志... (Ctrl+C 退出)');
226
+ }
227
+ const control = (0, service_log_1.openServiceLogStream)(filters, {
228
+ onLog: (entry) => {
229
+ received += 1;
230
+ if (options.json) {
231
+ (0, output_1.printStructuredResult)({ ok: true, data: entry });
232
+ }
233
+ else {
234
+ const time = pickLogTime(entry);
235
+ const level = colorizeLevel(entry.level || '-');
236
+ const host = entry.host ?? '-';
237
+ const msg = flattenMessage(entry.message);
238
+ console.log(`[${time}] [${level}] [${host}] ${msg}`);
239
+ }
240
+ if (maxCount > 0 && received >= maxCount) {
241
+ control.cancel();
242
+ }
243
+ },
244
+ onError: (message) => {
245
+ if (options.json) {
246
+ (0, output_1.printStructuredResult)({ ok: false, message });
247
+ }
248
+ else {
249
+ (0, output_1.printWarning)(message);
250
+ }
251
+ },
252
+ onClose: (code) => {
253
+ if (closed)
254
+ return;
255
+ closed = true;
256
+ if (!options.json) {
257
+ (0, output_1.printInfo)(`实时日志连接已关闭 (code=${code})`);
258
+ }
259
+ },
260
+ });
261
+ const onSigInt = () => {
262
+ if (!closed) {
263
+ control.cancel();
264
+ }
265
+ process.removeListener('SIGINT', onSigInt);
266
+ };
267
+ process.on('SIGINT', onSigInt);
268
+ });
269
+ }
270
+ function buildStreamFilters(options) {
271
+ const limit = Number(options.limit);
272
+ if (!Number.isFinite(limit) || limit <= 0) {
273
+ return new Error('--limit 必须为正整数');
274
+ }
275
+ const filters = { limit };
276
+ if (options.level)
277
+ filters.log_level = String(options.level);
278
+ if (options.requestId)
279
+ filters.request_id = String(options.requestId);
280
+ if (options.keyword)
281
+ filters.keyword = String(options.keyword);
282
+ if (options.serviceType)
283
+ filters.service_type = String(options.serviceType);
284
+ return filters;
285
+ }
286
+ //# sourceMappingURL=service-log.js.map
package/dist/index.js CHANGED
@@ -57,6 +57,7 @@ const link_1 = require("@/commands/link");
57
57
  const sync_1 = require("@/commands/sync");
58
58
  const org_1 = require("@/commands/org");
59
59
  const profile_1 = require("@/commands/profile");
60
+ const service_log_1 = require("@/commands/service-log");
60
61
  const updateCheck_1 = require("@/utils/updateCheck");
61
62
  const output_1 = require("@/utils/output");
62
63
  const config_2 = require("@/utils/config");
@@ -76,6 +77,7 @@ async function main() {
76
77
  (0, sync_1.registerSyncCommand)(program);
77
78
  (0, org_1.registerOrgCommand)(program);
78
79
  (0, profile_1.registerProfileCommand)(program);
80
+ (0, service_log_1.registerServiceLogCommand)(program);
79
81
  program.hook('preAction', (thisCommand) => {
80
82
  const opts = thisCommand.optsWithGlobals();
81
83
  if (opts.quiet) {
@@ -51,24 +51,23 @@ async function generateAllSkills(outputDir) {
51
51
  skillsGenerated: 0,
52
52
  errors: [],
53
53
  };
54
- //TODO 此部分目前硬编码 后续需要根据实际调整
55
54
  const categoryTypes = [
56
- { type: 'action', trigger: false, label: '动作' },
57
- { type: 'trigger', trigger: true, label: '触发器' },
58
- // { type: "tool", trigger: false, label: "工具" },
59
- // { type: "mcp", trigger: false, label: "MCP" },
60
- // { type: "model", trigger: false, label: "模型" },
61
- // { type: "memory", trigger: false, label: "记忆" },
55
+ { type: 'normal', trigger: false, label: '自动化' },
56
+ { type: 'normal-trigger', trigger: true, label: '自动化触发器' },
57
+ { type: 'mcp', trigger: true, label: 'MCP' },
58
+ { type: 'mcp-trigger', trigger: true, label: 'MCP触发器' },
62
59
  ];
63
60
  for (const ct of categoryTypes) {
64
61
  try {
65
- const categories = await (0, knowledge_1.getNodeCategories)({ type: ct.type });
62
+ const categories = await (0, knowledge_1.getNodeCategories)({ trigger: ct.trigger });
66
63
  progress.totalCategories += categories.length;
67
64
  (0, output_1.printInfo)(`发现 ${categories.length} 个${ct.label}分类`);
68
65
  const mdDir = path.join(outputDir, ct.type);
69
66
  fs.mkdirSync(mdDir, { recursive: true });
70
67
  for (const category of categories) {
71
- await processCategory(category, mdDir, progress, ct.trigger);
68
+ const categoryMdDir = path.join(mdDir, category.name);
69
+ fs.mkdirSync(categoryMdDir, { recursive: true });
70
+ await processCategory(category, categoryMdDir, progress, ct.trigger);
72
71
  }
73
72
  }
74
73
  catch (error) {
@@ -87,7 +86,7 @@ async function processCategory(category, mdDir, progress, trigger = false) {
87
86
  let hasMore = true;
88
87
  while (hasMore) {
89
88
  const result = await (0, knowledge_1.searchNodesByCategory)({
90
- app_domain_category: categoryKey,
89
+ category_name: categoryKey,
91
90
  trigger,
92
91
  page,
93
92
  size: batchSize,
@@ -130,7 +129,10 @@ async function processConnector(connector, category, mdDir, progress, trigger =
130
129
  }
131
130
  }
132
131
  async function generateSkillFile(action, category, connector, mdDir, progress) {
133
- const parameters = (0, format_1.configSchemaToParams)(action.config_schema?.sub_params);
132
+ const hasNodeSchema = !!action.node_schema;
133
+ const parameters = hasNodeSchema
134
+ ? (0, format_1.nodeSchemaToParams)(action.node_schema?.input_fields)
135
+ : (0, format_1.configSchemaToParams)(action.config_schema?.sub_params);
134
136
  const scenarios = (0, format_1.inferScenarios)(action.name, action.description);
135
137
  const skill = {
136
138
  name: action.name,
@@ -142,7 +144,7 @@ async function generateSkillFile(action, category, connector, mdDir, progress) {
142
144
  desc: category.desc || '',
143
145
  },
144
146
  action_type: action.action_type || 'action',
145
- action_key: action.action_key,
147
+ action_key: hasNodeSchema ? action.node_schema?.key || action.action_key : action.action_key,
146
148
  connector_id: action.connector_id,
147
149
  link_id: connector.id,
148
150
  action_id: action.id,
@@ -156,6 +158,21 @@ async function generateSkillFile(action, category, connector, mdDir, progress) {
156
158
  },
157
159
  parameters,
158
160
  scenarios,
161
+ node_schema: hasNodeSchema && action.node_schema
162
+ ? {
163
+ key: action.node_schema.key,
164
+ version: action.node_schema.version,
165
+ name: action.node_schema.name,
166
+ description: action.node_schema.description,
167
+ input_fields: (0, format_1.nodeSchemaToParams)(action.node_schema.input_fields),
168
+ output_fields: (action.node_schema.output_fields || []).map((o) => ({
169
+ key: o.key,
170
+ label: o.label,
171
+ type: o.type,
172
+ description: o.description ?? undefined,
173
+ })),
174
+ }
175
+ : undefined,
159
176
  };
160
177
  const safeName = (0, format_1.sanitizeFileName)(`${connector.name}_${action.name}`);
161
178
  try {
@@ -171,7 +188,39 @@ function skillToMarkdown(skill) {
171
188
  if (skill.description) {
172
189
  lines.push('## 功能描述', '', skill.description, '');
173
190
  }
174
- if (skill.parameters.length > 0) {
191
+ if (skill.node_schema) {
192
+ const ns = skill.node_schema;
193
+ lines.push('## Node Package 信息', '');
194
+ lines.push(`- **Schema Key**: \`${ns.key}\``);
195
+ lines.push(`- **Version**: ${ns.version}`);
196
+ if (ns.name)
197
+ lines.push(`- **Name**: ${ns.name}`);
198
+ if (ns.description)
199
+ lines.push(`- **Description**: ${ns.description}`);
200
+ lines.push('');
201
+ if (ns.input_fields.length > 0) {
202
+ lines.push('## 配置参数 (Input Fields)', '');
203
+ lines.push('| 字段名 | 显示名 | 类型 | 必填 | 说明 | 默认值 | 可选值 |');
204
+ lines.push('|--------|--------|------|------|------|--------|--------|');
205
+ for (const param of ns.input_fields) {
206
+ const options = (param.options || [])
207
+ ?.map((o) => (o.label !== o.key ? `\`${o.key}\` (${o.label})` : `\`${o.key}\``))
208
+ .join(', ') || '-';
209
+ lines.push(`| \`${param.name}\` | ${param.display_name} | ${param.type} | ${param.required ? '是' : '否'} | ${param.description || '-'} | ${param.default ?? '-'} | ${options} |`);
210
+ }
211
+ lines.push('');
212
+ }
213
+ if (ns.output_fields.length > 0) {
214
+ lines.push('## 输出字段', '');
215
+ lines.push('| 字段名 | 显示名 | 类型 | 说明 |');
216
+ lines.push('|--------|--------|------|------|');
217
+ for (const o of ns.output_fields) {
218
+ lines.push(`| \`${o.key}\` | ${o.label} | ${o.type} | ${o.description || '-'} |`);
219
+ }
220
+ lines.push('');
221
+ }
222
+ }
223
+ else if (skill.parameters.length > 0) {
175
224
  lines.push('## 配置参数', '');
176
225
  lines.push('| 字段名 | 显示名 | 类型 | 必填 | 说明 | 默认值 | 可选值 |');
177
226
  lines.push('|--------|--------|------|------|------|--------|--------|');
@@ -1,6 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.safeParseJSON = safeParseJSON;
4
+ exports.parseTimeRange = parseTimeRange;
4
5
  function safeParseJSON(value, fallback) {
5
6
  if (typeof value !== 'string')
6
7
  return fallback;
@@ -11,4 +12,19 @@ function safeParseJSON(value, fallback) {
11
12
  return fallback;
12
13
  }
13
14
  }
15
+ const UNIT_MS = {
16
+ s: 1000,
17
+ m: 60 * 1000,
18
+ h: 60 * 60 * 1000,
19
+ d: 24 * 60 * 60 * 1000,
20
+ };
21
+ function parseTimeRange(value) {
22
+ const trimmed = String(value).trim();
23
+ const match = trimmed.match(/^(\d+)([smhd])$/i);
24
+ if (!match)
25
+ return null;
26
+ const num = parseInt(match[1], 10);
27
+ const unit = match[2].toLowerCase();
28
+ return num * (UNIT_MS[unit] ?? 0);
29
+ }
14
30
  //# sourceMappingURL=common.js.map
@@ -33,6 +33,7 @@ var __importStar = (this && this.__importStar) || (function () {
33
33
  };
34
34
  })();
35
35
  Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.getAccessToken = getAccessToken;
36
37
  exports.setActiveProfile = setActiveProfile;
37
38
  exports.getActiveProfile = getActiveProfile;
38
39
  exports.loadConfig = loadConfig;
@@ -55,8 +56,8 @@ const PROJECT_RC = '.ai-flowrc';
55
56
  const DEFAULT_PROFILE_NAME = 'default';
56
57
  const DEFAULT_CONFIG = {
57
58
  baseUrl: 'https://poc.digitalsee.cn',
58
- token: '',
59
59
  insecure: false,
60
+ auth: null,
60
61
  };
61
62
  let activeProfileOverride = null;
62
63
  function ensureConfigDir() {
@@ -88,12 +89,18 @@ function buildProfileStoreFromFlat(raw) {
88
89
  profiles: {
89
90
  [DEFAULT_PROFILE_NAME]: {
90
91
  baseUrl: raw.baseUrl || DEFAULT_CONFIG.baseUrl,
91
- token: raw.token ?? DEFAULT_CONFIG.token,
92
+ auth: raw.auth ?? (raw.token ? { access_token: raw.token } : DEFAULT_CONFIG.auth),
92
93
  insecure: raw.insecure ?? DEFAULT_CONFIG.insecure,
93
94
  },
94
95
  },
95
96
  };
96
97
  }
98
+ /**
99
+ * 从 FlowConfig 中提取 access_token,不存在时返回空字符串。
100
+ */
101
+ function getAccessToken(config) {
102
+ return config.auth?.access_token ?? '';
103
+ }
97
104
  function setActiveProfile(name) {
98
105
  activeProfileOverride = name;
99
106
  try {
@@ -1,6 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.configSchemaToParams = configSchemaToParams;
4
+ exports.nodeSchemaToParams = nodeSchemaToParams;
4
5
  exports.inferScenarios = inferScenarios;
5
6
  exports.sanitizeFileName = sanitizeFileName;
6
7
  exports.fillConfigSchemaDefaults = fillConfigSchemaDefaults;
@@ -51,6 +52,19 @@ function inferFieldType(param) {
51
52
  }
52
53
  return 'string';
53
54
  }
55
+ function nodeSchemaToParams(inputFields) {
56
+ if (!inputFields || !Array.isArray(inputFields))
57
+ return [];
58
+ return inputFields.map((f) => ({
59
+ name: f.key,
60
+ type: f.type,
61
+ required: f.required ?? false,
62
+ description: f.help_text || '',
63
+ display_name: f.label,
64
+ options: f.options?.map((o) => ({ key: o.value, label: o.label })),
65
+ default: f.default_value,
66
+ }));
67
+ }
54
68
  function inferScenarios(actionName, description) {
55
69
  const scenarios = [];
56
70
  const text = `${actionName} ${description || ''}`.toLowerCase();
@@ -0,0 +1,87 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.getCachedNodePackageSupport = getCachedNodePackageSupport;
37
+ exports.getNodePackageSupportFor = getNodePackageSupportFor;
38
+ exports.checkAndCacheNodePackageSupport = checkAndCacheNodePackageSupport;
39
+ const fs = __importStar(require("fs"));
40
+ const path = __importStar(require("path"));
41
+ const os = __importStar(require("os"));
42
+ const node_1 = require("@/api/node");
43
+ const config_1 = require("@/utils/config");
44
+ const STATE_DIR = path.join(os.homedir(), '.ai-flow-cli');
45
+ function getStateFile() {
46
+ return path.join(STATE_DIR, `node-package-${(0, config_1.getActiveProfile)()}.json`);
47
+ }
48
+ function ensureStateDir() {
49
+ if (!fs.existsSync(STATE_DIR)) {
50
+ fs.mkdirSync(STATE_DIR, { recursive: true });
51
+ }
52
+ }
53
+ function getCachedNodePackageSupport() {
54
+ try {
55
+ const stateFile = getStateFile();
56
+ if (fs.existsSync(stateFile)) {
57
+ const content = fs.readFileSync(stateFile, 'utf-8');
58
+ const state = JSON.parse(content);
59
+ return state.supported;
60
+ }
61
+ }
62
+ catch {
63
+ return undefined;
64
+ }
65
+ return undefined;
66
+ }
67
+ function getNodePackageSupportFor(profileName) {
68
+ try {
69
+ const stateFile = path.join(STATE_DIR, `node-package-${profileName}.json`);
70
+ if (fs.existsSync(stateFile)) {
71
+ const content = fs.readFileSync(stateFile, 'utf-8');
72
+ const state = JSON.parse(content);
73
+ return state.supported;
74
+ }
75
+ }
76
+ catch {
77
+ return undefined;
78
+ }
79
+ return undefined;
80
+ }
81
+ async function checkAndCacheNodePackageSupport() {
82
+ const supported = await (0, node_1.isNodePackageSupported)();
83
+ ensureStateDir();
84
+ fs.writeFileSync(getStateFile(), JSON.stringify({ supported, checkedAt: Date.now() }), 'utf-8');
85
+ return supported;
86
+ }
87
+ //# sourceMappingURL=nodePackage.js.map
@@ -219,8 +219,8 @@ function createAuthServer() {
219
219
  return;
220
220
  }
221
221
  const port = addr.port;
222
- const waitForCode = createWaitForCode(server, 'http', port);
223
- resolve({ server, port, waitForCode });
222
+ const waitForResult = createWaitForCode(server, 'http', port);
223
+ resolve({ server, port, waitForResult });
224
224
  });
225
225
  });
226
226
  }
@@ -236,8 +236,8 @@ function createAuthServerHttps() {
236
236
  return;
237
237
  }
238
238
  const port = addr.port;
239
- const waitForCode = createWaitForCode(server, 'https', port);
240
- resolve({ server, port, waitForCode });
239
+ const waitForResult = createWaitForCode(server, 'https', port);
240
+ resolve({ server, port, waitForResult });
241
241
  });
242
242
  });
243
243
  }
@@ -300,14 +300,22 @@ function createWaitForCode(server, protocol, _port) {
300
300
  server.on('request', (req, res) => {
301
301
  const url = new URL(req.url || '/', `${protocol}://127.0.0.1`);
302
302
  const error = url.searchParams.get('error');
303
- const ak = url.searchParams.get('ak');
304
- if (!ak && !error) {
303
+ const accessToken = url.searchParams.get('access_token');
304
+ const refreshToken = url.searchParams.get('refresh_token');
305
+ const idToken = url.searchParams.get('id_token');
306
+ const tokenType = url.searchParams.get('token_type');
307
+ const expiresIn = url.searchParams.get('expires_in');
308
+ if (!accessToken && !error) {
305
309
  res.writeHead(200, { 'Content-Type': 'text/html; charset=utf-8' });
306
- const str = "`${location.href.substring(0, location.href.indexOf('#'))}?ak=${token}`";
310
+ const str = "`${location.href.substring(0, location.href.indexOf('#'))}?access_token=${token}&refresh_token=${refresh_token}&id_token=${id_token}&token_type=${token_type}&expires_in=${expires_in}`";
307
311
  res.end(renderPage('等待授权回调', `<p>正在等待浏览器授权,请勿关闭此页面...</p><div class="spinner"></div>`, '').replace('</body>', `<script>
308
312
  (function(){
309
313
  var params = new URLSearchParams(location.hash.substring(1));
310
314
  var token = params.get('access_token');
315
+ var refresh_token = params.get('refresh_token');
316
+ var id_token = params.get('id_token');
317
+ var token_type = params.get('token_type');
318
+ var expires_in = params.get('expires_in');
311
319
  location.href = ${str};
312
320
  })();
313
321
  </script></body>`));
@@ -325,7 +333,18 @@ function createWaitForCode(server, protocol, _port) {
325
333
  res.writeHead(200, { 'Content-Type': 'text/html; charset=utf-8' });
326
334
  res.end(renderPage('登录成功', '<p>请关闭此页面返回终端</p>', '').replace('card">', 'card success">'));
327
335
  server.close();
328
- resolveCode(ak);
336
+ const result = {
337
+ access_token: accessToken ?? '',
338
+ refresh_token: refreshToken ?? '',
339
+ id_token: idToken ?? '',
340
+ token_type: tokenType ?? '',
341
+ expires_in: expiresIn ? Number(expiresIn) : 0,
342
+ };
343
+ if (!accessToken) {
344
+ rejectCode(new Error('授权回调缺少 access_token'));
345
+ return;
346
+ }
347
+ resolveCode(result);
329
348
  });
330
349
  server.on('error', (err) => {
331
350
  clearTimeout(timer);