@bintel/dimens-cli
Advanced tools
| import { t as __exportAll } from "./rolldown-runtime-95iHPtFO.mjs"; | ||
| import { n as logger } from "./logger-CEOtAYhF.mjs"; | ||
| import { a as AuthSDK, i as ColumnSDK, l as getVersion, n as RowSDK, o as DimensClient, r as ProjectSDK, s as FlowChatSDK, t as SheetSDK } from "./sheet-jiBqJC3e.mjs"; | ||
| import { readFile, writeFile } from "fs/promises"; | ||
| import { join } from "path"; | ||
| import { homedir } from "os"; | ||
| import { existsSync, readFileSync, readdirSync, statSync } from "node:fs"; | ||
| import { dirname as dirname$1, join as join$1, relative, resolve } from "node:path"; | ||
| import { fileURLToPath } from "node:url"; | ||
| //#region src/core/config.ts | ||
| /** | ||
| * 配置管理 | ||
| */ | ||
| const DEFAULT_CONFIG = { | ||
| version: "1.0.0", | ||
| profile: {}, | ||
| skills: {}, | ||
| preferences: {} | ||
| }; | ||
| var ConfigManager = class { | ||
| configPath; | ||
| config; | ||
| constructor() { | ||
| this.configPath = join(homedir(), ".dimens-cli", "config.json"); | ||
| this.config = DEFAULT_CONFIG; | ||
| } | ||
| async load() { | ||
| try { | ||
| const data = await readFile(this.configPath, "utf-8"); | ||
| const parsed = JSON.parse(data); | ||
| this.config = { | ||
| ...DEFAULT_CONFIG, | ||
| ...parsed, | ||
| profile: { | ||
| ...DEFAULT_CONFIG.profile, | ||
| ...parsed.profile || {} | ||
| }, | ||
| skills: parsed.skills || {}, | ||
| preferences: parsed.preferences || {} | ||
| }; | ||
| logger.debug("配置加载成功", { path: this.configPath }); | ||
| } catch (error) { | ||
| logger.debug("配置文件不存在,使用默认配置"); | ||
| this.config = { | ||
| ...DEFAULT_CONFIG, | ||
| profile: { ...DEFAULT_CONFIG.profile } | ||
| }; | ||
| } | ||
| } | ||
| async save() { | ||
| try { | ||
| const { mkdir } = await import("fs/promises"); | ||
| await mkdir(join(homedir(), ".dimens-cli"), { recursive: true }); | ||
| await writeFile(this.configPath, JSON.stringify(this.config, null, 2), "utf-8"); | ||
| logger.debug("配置保存成功", { path: this.configPath }); | ||
| } catch (error) { | ||
| logger.error("配置保存失败", { error: String(error) }); | ||
| throw error; | ||
| } | ||
| } | ||
| get(key) { | ||
| return this.config[key]; | ||
| } | ||
| set(key, value) { | ||
| this.config[key] = value; | ||
| } | ||
| getAll() { | ||
| return { | ||
| ...this.config, | ||
| profile: { ...this.config.profile }, | ||
| skills: { ...this.config.skills }, | ||
| preferences: { ...this.config.preferences } | ||
| }; | ||
| } | ||
| }; | ||
| const config = new ConfigManager(); | ||
| //#endregion | ||
| //#region src/commands/registry.ts | ||
| const registeredCommands = /* @__PURE__ */ new Map(); | ||
| const registeredGroups = /* @__PURE__ */ new Map(); | ||
| const qualifiedCommands = /* @__PURE__ */ new Map(); | ||
| function createCommandGroup(name, description) { | ||
| const group = { | ||
| name, | ||
| description, | ||
| commands: [] | ||
| }; | ||
| registeredGroups.set(name, group); | ||
| return group; | ||
| } | ||
| function registerCommand(command) { | ||
| if (registeredCommands.has(command.name)) logger.warn(`命令 ${command.name} 已存在,将被覆盖`); | ||
| registeredCommands.set(command.name, command); | ||
| if (command.aliases) command.aliases.forEach((alias) => { | ||
| registeredCommands.set(alias, command); | ||
| }); | ||
| logger.debug(`命令已注册: ${command.name}`); | ||
| } | ||
| function registerGroupCommand(groupName, command) { | ||
| (registeredGroups.get(groupName) || createCommandGroup(groupName, groupName)).commands.push(command); | ||
| const qualifiedName = `${groupName}:${command.name}`; | ||
| qualifiedCommands.set(qualifiedName, command); | ||
| if (groupName === "system" || groupName === "auth") { | ||
| registerCommand(command); | ||
| return; | ||
| } | ||
| if (command.aliases) command.aliases.forEach((alias) => { | ||
| qualifiedCommands.set(`${groupName}:${alias}`, command); | ||
| }); | ||
| logger.debug(`命令已注册: ${qualifiedName}`); | ||
| } | ||
| function getCommand(name) { | ||
| return registeredCommands.get(name); | ||
| } | ||
| function getGroupCommand(groupName, commandName) { | ||
| return qualifiedCommands.get(`${groupName}:${commandName}`); | ||
| } | ||
| function getAllCommands() { | ||
| const uniqueCommands = new Set(registeredCommands.values()); | ||
| return Array.from(uniqueCommands); | ||
| } | ||
| function getCommandGroup(name) { | ||
| return registeredGroups.get(name); | ||
| } | ||
| function getAllCommandGroups() { | ||
| return Array.from(registeredGroups.values()); | ||
| } | ||
| function clearCommands() { | ||
| registeredCommands.clear(); | ||
| registeredGroups.clear(); | ||
| qualifiedCommands.clear(); | ||
| logger.debug("所有命令已清除"); | ||
| } | ||
| function createCommand(name, description, handler, options) { | ||
| return { | ||
| name, | ||
| description, | ||
| handler, | ||
| ...options | ||
| }; | ||
| } | ||
| //#endregion | ||
| //#region src/skills/mappings.ts | ||
| const SKILL_MAPPINGS = { | ||
| "dimens-system-orchestrator": { | ||
| version: "1.0.0", | ||
| tags: [ | ||
| "system", | ||
| "orchestrator", | ||
| "planner", | ||
| "routing", | ||
| "builder" | ||
| ], | ||
| commandGroups: ["skill"], | ||
| commands: [ | ||
| "skill recommend", | ||
| "skill info", | ||
| "skill show" | ||
| ], | ||
| sdkModules: [], | ||
| toolNames: ["system_decomposition", "skill_routing"] | ||
| }, | ||
| "dimens-workflow": { | ||
| version: "1.0.0", | ||
| tags: [ | ||
| "workflow", | ||
| "flow", | ||
| "ai", | ||
| "project", | ||
| "team" | ||
| ], | ||
| commandGroups: ["ai"], | ||
| commands: ["ai chat-completions"], | ||
| sdkModules: ["FlowChatSDK", "DimensSDK.ai"], | ||
| toolNames: [ | ||
| "flow_list", | ||
| "project_workflow_binding_list", | ||
| "flow_run_invoke", | ||
| "flow_run_debug", | ||
| "flow_config_get" | ||
| ] | ||
| }, | ||
| "dimens-key-auth": { | ||
| version: "1.0.0", | ||
| tags: [ | ||
| "auth", | ||
| "api-key", | ||
| "token", | ||
| "login", | ||
| "security" | ||
| ], | ||
| commandGroups: ["auth"], | ||
| commands: [ | ||
| "auth api-key-login", | ||
| "auth login", | ||
| "auth refresh", | ||
| "auth status", | ||
| "auth profile" | ||
| ], | ||
| sdkModules: ["AuthSDK", "DimensSDK.auth"], | ||
| toolNames: [ | ||
| "api_key_create", | ||
| "api_key_list", | ||
| "api_key_status", | ||
| "api_key_delete", | ||
| "api_key_reset_secret", | ||
| "api_key_log_page" | ||
| ] | ||
| }, | ||
| "dimens-team": { | ||
| version: "1.0.0", | ||
| tags: [ | ||
| "team", | ||
| "project", | ||
| "tenant", | ||
| "member", | ||
| "context" | ||
| ], | ||
| commandGroups: ["auth", "project"], | ||
| commands: [ | ||
| "auth use-team", | ||
| "auth use-project", | ||
| "project list", | ||
| "project info", | ||
| "project create", | ||
| "project update", | ||
| "project trash", | ||
| "project restore" | ||
| ], | ||
| sdkModules: ["ProjectSDK", "DimensSDK.project"], | ||
| toolNames: [ | ||
| "team_info", | ||
| "team_user_list", | ||
| "project_list", | ||
| "project_info", | ||
| "project_create", | ||
| "project_update", | ||
| "project_trash", | ||
| "project_restore" | ||
| ] | ||
| }, | ||
| "dimens-table": { | ||
| version: "1.0.0", | ||
| tags: [ | ||
| "table", | ||
| "sheet", | ||
| "row", | ||
| "column", | ||
| "view" | ||
| ], | ||
| commandGroups: [ | ||
| "sheet", | ||
| "column", | ||
| "row" | ||
| ], | ||
| commands: [ | ||
| "sheet list", | ||
| "sheet tree", | ||
| "sheet create", | ||
| "sheet info", | ||
| "sheet update", | ||
| "sheet delete", | ||
| "column list", | ||
| "column create", | ||
| "column update", | ||
| "column delete", | ||
| "row page", | ||
| "row info", | ||
| "row create", | ||
| "row update", | ||
| "row delete", | ||
| "row set-cell" | ||
| ], | ||
| sdkModules: [ | ||
| "SheetSDK", | ||
| "ColumnSDK", | ||
| "RowSDK", | ||
| "DimensSDK.sheet", | ||
| "DimensSDK.column", | ||
| "DimensSDK.row" | ||
| ], | ||
| toolNames: [ | ||
| "sheet_list", | ||
| "sheet_info", | ||
| "column_list", | ||
| "column_create", | ||
| "row_page", | ||
| "row_update", | ||
| "row_set_cell" | ||
| ] | ||
| }, | ||
| "dimens-permission": { | ||
| version: "1.0.0", | ||
| tags: [ | ||
| "permission", | ||
| "acl", | ||
| "row-policy", | ||
| "yjs", | ||
| "security" | ||
| ], | ||
| commandGroups: [], | ||
| commands: [], | ||
| sdkModules: [], | ||
| toolNames: [ | ||
| "project_authority_check", | ||
| "permission_resolve", | ||
| "column_permission_resolve", | ||
| "row_policy_check", | ||
| "yjs_permission_snapshot" | ||
| ] | ||
| }, | ||
| "dimens-report": { | ||
| version: "1.0.0", | ||
| tags: [ | ||
| "report", | ||
| "chart", | ||
| "dashboard", | ||
| "parameter", | ||
| "query" | ||
| ], | ||
| commandGroups: [], | ||
| commands: [], | ||
| sdkModules: [], | ||
| toolNames: [ | ||
| "report_list", | ||
| "report_info", | ||
| "report_widget_list", | ||
| "report_parameter_list", | ||
| "report_query", | ||
| "report_export" | ||
| ] | ||
| } | ||
| }; | ||
| function getSkillMapping(name) { | ||
| return SKILL_MAPPINGS[name]; | ||
| } | ||
| //#endregion | ||
| //#region src/skills/index.ts | ||
| /** | ||
| * 技能发现与读取 | ||
| */ | ||
| function getPackageRoot() { | ||
| const currentDir = dirname$1(fileURLToPath(import.meta.url)); | ||
| return [resolve(currentDir, "../"), resolve(currentDir, "../../")].find((candidate) => existsSync(join$1(candidate, "package.json")) && existsSync(join$1(candidate, "skills"))) ?? resolve(currentDir, "../../"); | ||
| } | ||
| function getSkillsRoot() { | ||
| return join$1(getPackageRoot(), "skills"); | ||
| } | ||
| function parseFrontmatter(content) { | ||
| const lines = content.split("\n"); | ||
| if (lines[0]?.trim() !== "---") return {}; | ||
| let i = 1; | ||
| const data = {}; | ||
| while (i < lines.length) { | ||
| const line = lines[i]; | ||
| if (line?.trim() === "---") break; | ||
| if (line?.startsWith("name:")) { | ||
| data.name = line.slice(5).trim(); | ||
| i += 1; | ||
| continue; | ||
| } | ||
| if (line?.startsWith("description:")) { | ||
| const inline = line.slice(12).trim(); | ||
| if (inline && inline !== "|") { | ||
| data.description = inline; | ||
| i += 1; | ||
| continue; | ||
| } | ||
| i += 1; | ||
| const block = []; | ||
| while (i < lines.length) { | ||
| const next = lines[i]; | ||
| if (!next) { | ||
| block.push(""); | ||
| i += 1; | ||
| continue; | ||
| } | ||
| if (!next.startsWith(" ")) break; | ||
| block.push(next.slice(2)); | ||
| i += 1; | ||
| } | ||
| data.description = block.join("\n").trim(); | ||
| continue; | ||
| } | ||
| i += 1; | ||
| } | ||
| return data; | ||
| } | ||
| function listReferenceFiles(referencesDir) { | ||
| if (!existsSync(referencesDir)) return []; | ||
| return readdirSync(referencesDir).filter((file) => file.endsWith(".md")).sort().map((file) => join$1(referencesDir, file)); | ||
| } | ||
| function loadSkillFromDirectory(skillDir) { | ||
| const skillPath = join$1(skillDir, "SKILL.md"); | ||
| if (!existsSync(skillPath) || !statSync(skillPath).isFile()) return; | ||
| const frontmatter = parseFrontmatter(readFileSync(skillPath, "utf8")); | ||
| const name = frontmatter.name?.trim(); | ||
| const description = frontmatter.description?.trim(); | ||
| if (!name || !description) return; | ||
| const referencesDir = join$1(skillDir, "references"); | ||
| const mapping = getSkillMapping(name); | ||
| const skill = { | ||
| name, | ||
| description, | ||
| skillPath, | ||
| references: listReferenceFiles(referencesDir), | ||
| ...mapping | ||
| }; | ||
| if (existsSync(referencesDir)) skill.referencesDir = referencesDir; | ||
| return skill; | ||
| } | ||
| function discoverSkills() { | ||
| const skillsRoot = getSkillsRoot(); | ||
| if (!existsSync(skillsRoot)) return []; | ||
| return readdirSync(skillsRoot).map((entry) => join$1(skillsRoot, entry)).filter((entryPath) => statSync(entryPath).isDirectory()).map(loadSkillFromDirectory).filter((skill) => Boolean(skill)).sort((a, b) => a.name.localeCompare(b.name, "zh-CN")); | ||
| } | ||
| const SKILLS = discoverSkills(); | ||
| function getSkill(name) { | ||
| return SKILLS.find((skill) => skill.name === name); | ||
| } | ||
| function getAllSkills() { | ||
| return [...SKILLS]; | ||
| } | ||
| function getSkillsRootPath() { | ||
| return getSkillsRoot(); | ||
| } | ||
| //#endregion | ||
| //#region src/commands/help.ts | ||
| function findRelatedSkills(groupName, commandName) { | ||
| const qualifiedCommand = commandName ? `${groupName} ${commandName}` : void 0; | ||
| return getAllSkills().filter((skill) => { | ||
| const matchesGroup = skill.commandGroups?.includes(groupName) ?? false; | ||
| const matchesCommand = qualifiedCommand ? skill.commands?.includes(qualifiedCommand) ?? false : false; | ||
| return matchesGroup || matchesCommand; | ||
| }).map((skill) => skill.name).sort((a, b) => a.localeCompare(b, "zh-CN")); | ||
| } | ||
| function printRelatedSkills(groupName, commandName) { | ||
| const relatedSkills = findRelatedSkills(groupName, commandName); | ||
| if (relatedSkills.length === 0) return; | ||
| console.log("相关 Skill:"); | ||
| relatedSkills.forEach((skillName) => { | ||
| console.log(` - ${skillName}`); | ||
| }); | ||
| } | ||
| const helpCommand = { | ||
| name: "help", | ||
| description: "显示帮助信息", | ||
| usage: "help [command] [subcommand]", | ||
| aliases: ["h", "?"], | ||
| handler: async (args) => { | ||
| if (args.length > 0) { | ||
| const groupName = args[0]; | ||
| const commandName = args[1]; | ||
| if (!groupName) return; | ||
| const group = getCommandGroup(groupName); | ||
| if (!group) { | ||
| console.log(`未找到命令组: ${groupName}`); | ||
| return; | ||
| } | ||
| if (commandName) { | ||
| const command = group.commands.find((c) => c.name === commandName || c.aliases?.includes(commandName)); | ||
| if (!command) { | ||
| console.log(`未找到命令: ${groupName} ${commandName}`); | ||
| return; | ||
| } | ||
| console.log(`\n命令: ${group.name} ${command.name}`); | ||
| console.log(`描述: ${command.description}`); | ||
| if (command.usage) console.log(`用法: ${command.usage}`); | ||
| if (command.aliases && command.aliases.length > 0) console.log(`别名: ${command.aliases.join(", ")}`); | ||
| if (command.examples && command.examples.length > 0) { | ||
| console.log("示例:"); | ||
| command.examples.forEach((example) => { | ||
| console.log(` ${example}`); | ||
| }); | ||
| } | ||
| printRelatedSkills(group.name, command.name); | ||
| console.log(""); | ||
| return; | ||
| } | ||
| console.log(`\n命令组: ${group.name}`); | ||
| console.log(`描述: ${group.description}`); | ||
| console.log("可用命令:"); | ||
| group.commands.forEach((command) => { | ||
| console.log(` ${command.name.padEnd(15)} ${command.description}`); | ||
| }); | ||
| printRelatedSkills(group.name); | ||
| console.log(""); | ||
| return; | ||
| } | ||
| console.log("\nDimens CLI - 多维项目开发助手"); | ||
| console.log(`版本: ${getVersion()}\n`); | ||
| console.log("可用命令组:\n"); | ||
| getAllCommandGroups().forEach((group) => { | ||
| console.log(` ${group.name.padEnd(15)} ${group.description}`); | ||
| }); | ||
| console.log("\n使用 \"help [group]\" 查看命令组,使用 \"help [group] [command]\" 查看具体命令"); | ||
| console.log("使用 \"help skill\" 查看技能命令组,使用 \"skill info <name>\" 查看具体 Skill\n"); | ||
| } | ||
| }; | ||
| function registerHelpCommand() { | ||
| createCommandGroup("system", "系统命令"); | ||
| registerGroupCommand("system", helpCommand); | ||
| } | ||
| //#endregion | ||
| //#region src/commands/version.ts | ||
| const versionCommand = { | ||
| name: "version", | ||
| description: "显示版本信息", | ||
| usage: "version", | ||
| aliases: [ | ||
| "v", | ||
| "-v", | ||
| "--version" | ||
| ], | ||
| handler: async () => { | ||
| console.log(`Dimens CLI v${getVersion()}`); | ||
| } | ||
| }; | ||
| function registerVersionCommand() { | ||
| registerGroupCommand("system", versionCommand); | ||
| } | ||
| //#endregion | ||
| //#region src/core/context.ts | ||
| const DEFAULT_BASE_URL = "https://dimens.bintelai.com/api"; | ||
| function resolveContext(args = {}, profile = {}) { | ||
| const context = { output: args.output ?? profile.output ?? "table" }; | ||
| const baseUrl = args.baseUrl ?? process.env.DIMENS_BASE_URL ?? profile.baseUrl ?? "https://dimens.bintelai.com/api"; | ||
| const token = args.token ?? process.env.DIMENS_TOKEN ?? profile.token; | ||
| const refreshToken = args.refreshToken ?? profile.refreshToken; | ||
| const teamId = args.teamId ?? process.env.DIMENS_TEAM_ID ?? profile.teamId; | ||
| const projectId = args.projectId ?? process.env.DIMENS_PROJECT_ID ?? profile.projectId; | ||
| context.baseUrl = baseUrl; | ||
| if (token !== void 0) context.token = token; | ||
| if (refreshToken !== void 0) context.refreshToken = refreshToken; | ||
| if (teamId !== void 0) context.teamId = teamId; | ||
| if (projectId !== void 0) context.projectId = projectId; | ||
| return context; | ||
| } | ||
| //#endregion | ||
| //#region src/core/output.ts | ||
| function formatSuccess(message, data, mode) { | ||
| if (mode === "json") return JSON.stringify({ | ||
| success: true, | ||
| message, | ||
| data | ||
| }, null, 2); | ||
| if (mode === "raw") return [message, typeof data === "string" ? data : JSON.stringify(data)].join("\n"); | ||
| return [message, JSON.stringify(data, null, 2)].join("\n"); | ||
| } | ||
| function formatError(message, mode, options) { | ||
| const relatedSkills = options?.relatedSkills ?? []; | ||
| if (mode === "json") return JSON.stringify({ | ||
| success: false, | ||
| message, | ||
| relatedSkills | ||
| }, null, 2); | ||
| if (relatedSkills.length === 0) return message; | ||
| return [ | ||
| message, | ||
| "", | ||
| "相关 Skill:", | ||
| ...relatedSkills.map((skill) => `- ${skill}`) | ||
| ].join("\n"); | ||
| } | ||
| //#endregion | ||
| //#region src/commands/execution-context.ts | ||
| let currentContext = {}; | ||
| function setExecutionContext(context) { | ||
| currentContext = context; | ||
| } | ||
| function clearExecutionContext() { | ||
| currentContext = {}; | ||
| } | ||
| function getRelatedSkillsForExecutionContext() { | ||
| const { groupName, commandName } = currentContext; | ||
| if (!groupName) return []; | ||
| const qualifiedCommand = commandName ? `${groupName} ${commandName}` : void 0; | ||
| return getAllSkills().filter((skill) => { | ||
| const matchesGroup = skill.commandGroups?.includes(groupName) ?? false; | ||
| const matchesCommand = qualifiedCommand ? skill.commands?.includes(qualifiedCommand) ?? false : false; | ||
| return matchesGroup || matchesCommand; | ||
| }).map((skill) => skill.name).sort((a, b) => a.localeCompare(b, "zh-CN")); | ||
| } | ||
| function getRelatedSkillObjectsForExecutionContext() { | ||
| const relatedSkillNames = new Set(getRelatedSkillsForExecutionContext()); | ||
| return getAllSkills().filter((skill) => relatedSkillNames.has(skill.name)); | ||
| } | ||
| //#endregion | ||
| //#region src/commands/utils.ts | ||
| function parseFlags(args) { | ||
| const flags = {}; | ||
| for (let index = 0; index < args.length; index += 1) { | ||
| const current = args[index]; | ||
| if (!current?.startsWith("--")) continue; | ||
| const normalized = current.slice(2); | ||
| const equalIndex = normalized.indexOf("="); | ||
| if (equalIndex >= 0) { | ||
| const key = normalized.slice(0, equalIndex); | ||
| flags[key] = normalized.slice(equalIndex + 1) || "true"; | ||
| continue; | ||
| } | ||
| const next = args[index + 1]; | ||
| if (next && !next.startsWith("--")) { | ||
| flags[normalized] = next; | ||
| index += 1; | ||
| continue; | ||
| } | ||
| flags[normalized] = "true"; | ||
| } | ||
| return flags; | ||
| } | ||
| function getProfile() { | ||
| return config.get("profile"); | ||
| } | ||
| function saveProfile(profile) { | ||
| config.set("profile", profile); | ||
| return config.save(); | ||
| } | ||
| function mergeProfile(patch) { | ||
| return { | ||
| ...getProfile(), | ||
| ...patch | ||
| }; | ||
| } | ||
| function getContext(flags = {}) { | ||
| const contextArgs = {}; | ||
| if (flags["base-url"]) contextArgs.baseUrl = flags["base-url"]; | ||
| if (flags.token) contextArgs.token = flags.token; | ||
| if (flags["team-id"]) contextArgs.teamId = flags["team-id"]; | ||
| if (flags["project-id"]) contextArgs.projectId = flags["project-id"]; | ||
| if (flags.output === "json" || flags.output === "raw" || flags.output === "table") contextArgs.output = flags.output; | ||
| return resolveContext(contextArgs, getProfile()); | ||
| } | ||
| function createClient(context) { | ||
| if (!context.baseUrl) throw new Error("缺少 baseUrl,请先执行 auth login 或传入 --base-url"); | ||
| const options = { baseUrl: context.baseUrl }; | ||
| if (context.token) options.token = context.token; | ||
| if (context.refreshToken) options.refreshToken = context.refreshToken; | ||
| if (context.teamId) options.teamId = context.teamId; | ||
| if (context.projectId) options.projectId = context.projectId; | ||
| return new DimensClient(options); | ||
| } | ||
| function printSuccess(context, message, data) { | ||
| console.log(formatSuccess(message, data, context.output)); | ||
| } | ||
| function printError(context, error) { | ||
| const message = error instanceof Error ? error.message : String(error); | ||
| const relatedSkills = getRelatedSkillsForExecutionContext(); | ||
| console.log(formatError(message, context.output, { relatedSkills })); | ||
| process.exitCode = 1; | ||
| } | ||
| function requireTeamId(context, flags) { | ||
| const teamId = flags["team-id"] || context.teamId; | ||
| if (!teamId) throw new Error("缺少 teamId,请先执行 auth use-team 或传入 --team-id"); | ||
| return teamId; | ||
| } | ||
| function requireProjectId(context, flags) { | ||
| const projectId = flags["project-id"] || context.projectId; | ||
| if (!projectId) throw new Error("缺少 projectId,请先执行 auth use-project 或传入 --project-id"); | ||
| return projectId; | ||
| } | ||
| function requireSheetId(flags, args) { | ||
| const sheetId = flags["sheet-id"] || args[0]; | ||
| if (!sheetId) throw new Error("缺少 sheetId,请传入 --sheet-id 或 sheet <command> <sheetId>"); | ||
| return sheetId; | ||
| } | ||
| //#endregion | ||
| //#region src/commands/ai/index.ts | ||
| function registerAICommands() { | ||
| createCommandGroup("ai", "AI 对话"); | ||
| registerGroupCommand("ai", createCommand("chat-completions", "调用工作流 OpenAI 兼容聊天接口", async (args) => { | ||
| const flags = parseFlags(args); | ||
| const context = getContext(flags); | ||
| try { | ||
| const teamId = requireTeamId(context, flags); | ||
| const message = flags.message; | ||
| if (!message) throw new Error("缺少 message,请传入 --message"); | ||
| const sdk = new FlowChatSDK(createClient(context)); | ||
| const payload = { | ||
| model: flags.model || "default", | ||
| messages: [{ | ||
| role: "user", | ||
| content: message | ||
| }], | ||
| stream: flags.stream === "true" | ||
| }; | ||
| if (flags.user) payload.user = flags.user; | ||
| printSuccess(context, "AI 对话调用成功", (await sdk.completions(teamId, payload)).data); | ||
| } catch (error) { | ||
| printError(context, error); | ||
| } | ||
| }, { | ||
| usage: "ai chat-completions --message <text> [--model default] [--team-id <teamId>]", | ||
| examples: ["dimens-cli ai chat-completions --message \"你好\" --model default"] | ||
| })); | ||
| } | ||
| //#endregion | ||
| //#region src/commands/auth/index.ts | ||
| function registerAuthCommands() { | ||
| createCommandGroup("auth", "认证与上下文"); | ||
| registerGroupCommand("auth", createCommand("login", "登录并保存本地凭证", async (args) => { | ||
| const flags = parseFlags(args); | ||
| const context = getContext(flags); | ||
| try { | ||
| const username = flags.username; | ||
| const password = flags.password; | ||
| if (!username || !password) throw new Error("缺少登录参数,请传入 --username 和 --password"); | ||
| const result = await new AuthSDK(createClient(context)).login({ | ||
| username, | ||
| password | ||
| }); | ||
| const nextProfile = mergeProfile(context.baseUrl ? { | ||
| baseUrl: context.baseUrl, | ||
| token: result.data.token | ||
| } : { token: result.data.token }); | ||
| if (result.data.refreshToken) nextProfile.refreshToken = result.data.refreshToken; | ||
| await saveProfile(nextProfile); | ||
| printSuccess(context, "登录成功", result.data); | ||
| } catch (error) { | ||
| printError(context, error); | ||
| } | ||
| }, { | ||
| usage: "auth login --username <name> --password <password> [--base-url <url>]", | ||
| examples: ["dimens-cli auth login --username admin --password 123456", "dimens-cli auth login --base-url https://custom.example.com --username admin --password 123456"] | ||
| })); | ||
| registerGroupCommand("auth", createCommand("api-key-login", "使用 apiKey 和 apiSecret 登录并换取 token", async (args) => { | ||
| const flags = parseFlags(args); | ||
| const context = getContext(flags); | ||
| try { | ||
| const apiKey = flags["api-key"]; | ||
| const apiSecret = flags["api-secret"]; | ||
| if (!apiKey || !apiSecret) throw new Error("缺少登录参数,请传入 --api-key 和 --api-secret"); | ||
| const result = await new AuthSDK(createClient(context)).loginByApiKey({ | ||
| apiKey, | ||
| apiSecret | ||
| }); | ||
| const nextProfile = mergeProfile(context.baseUrl ? { | ||
| baseUrl: context.baseUrl, | ||
| token: result.data.token | ||
| } : { token: result.data.token }); | ||
| if (result.data.refreshToken) nextProfile.refreshToken = result.data.refreshToken; | ||
| await saveProfile(nextProfile); | ||
| printSuccess(context, "API Key 登录成功", result.data); | ||
| } catch (error) { | ||
| printError(context, error); | ||
| } | ||
| }, { | ||
| usage: "auth api-key-login --api-key <apiKey> --api-secret <apiSecret> [--base-url <url>]", | ||
| examples: ["dimens-cli auth api-key-login --api-key ak_xxx --api-secret sk_xxx", "dimens-cli auth api-key-login --base-url https://custom.example.com --api-key ak_xxx --api-secret sk_xxx"] | ||
| })); | ||
| registerGroupCommand("auth", createCommand("refresh", "刷新 token", async (args) => { | ||
| const context = getContext(parseFlags(args)); | ||
| try { | ||
| const result = await new AuthSDK(createClient(context)).refreshToken(); | ||
| const nextProfile = mergeProfile({ token: result.data.token }); | ||
| const refreshToken = result.data.refreshToken ?? context.refreshToken; | ||
| if (refreshToken) nextProfile.refreshToken = refreshToken; | ||
| await saveProfile(nextProfile); | ||
| printSuccess(context, "刷新成功", result.data); | ||
| } catch (error) { | ||
| printError(context, error); | ||
| } | ||
| }, { usage: "auth refresh [--base-url <url>]" })); | ||
| registerGroupCommand("auth", createCommand("status", "查看当前上下文", async (args) => { | ||
| const context = getContext(parseFlags(args)); | ||
| printSuccess(context, "当前上下文", context); | ||
| }, { usage: "auth status" })); | ||
| registerGroupCommand("auth", createCommand("use-team", "设置默认团队", async (args) => { | ||
| const context = getContext(); | ||
| try { | ||
| const teamId = args[0]; | ||
| if (!teamId) throw new Error("缺少 teamId,请传入 auth use-team <teamId>"); | ||
| await saveProfile(mergeProfile({ teamId })); | ||
| printSuccess(context, "默认团队已更新", { teamId }); | ||
| } catch (error) { | ||
| printError(context, error); | ||
| } | ||
| }, { usage: "auth use-team <teamId>" })); | ||
| registerGroupCommand("auth", createCommand("use-project", "设置默认项目", async (args) => { | ||
| const context = getContext(); | ||
| try { | ||
| const projectId = args[0]; | ||
| if (!projectId) throw new Error("缺少 projectId,请传入 auth use-project <projectId>"); | ||
| await saveProfile(mergeProfile({ projectId })); | ||
| printSuccess(context, "默认项目已更新", { projectId }); | ||
| } catch (error) { | ||
| printError(context, error); | ||
| } | ||
| }, { usage: "auth use-project <projectId>" })); | ||
| registerGroupCommand("auth", createCommand("profile", "查看本地 profile", async (args) => { | ||
| printSuccess(getContext(parseFlags(args)), "本地 Profile", getProfile()); | ||
| }, { usage: "auth profile" })); | ||
| } | ||
| //#endregion | ||
| //#region src/commands/column/index.ts | ||
| function registerColumnCommands() { | ||
| createCommandGroup("column", "字段管理"); | ||
| registerGroupCommand("column", createCommand("list", "获取字段列表", async (args) => { | ||
| const flags = parseFlags(args); | ||
| const context = getContext(flags); | ||
| try { | ||
| const teamId = requireTeamId(context, flags); | ||
| const projectId = requireProjectId(context, flags); | ||
| const sheetId = requireSheetId(flags, args); | ||
| printSuccess(context, "字段列表获取成功", (await new ColumnSDK(createClient(context)).list(teamId, projectId, sheetId)).data); | ||
| } catch (error) { | ||
| printError(context, error); | ||
| } | ||
| })); | ||
| registerGroupCommand("column", createCommand("create", "创建字段", async (args) => { | ||
| const flags = parseFlags(args); | ||
| const context = getContext(flags); | ||
| try { | ||
| const teamId = requireTeamId(context, flags); | ||
| const projectId = requireProjectId(context, flags); | ||
| const sheetId = requireSheetId(flags, args); | ||
| const label = flags.label || flags.title; | ||
| if (!label) throw new Error("缺少字段标题,请传入 --label 或兼容参数 --title"); | ||
| const sdk = new ColumnSDK(createClient(context)); | ||
| const payload = { label }; | ||
| if (flags.type) payload.type = flags.type; | ||
| printSuccess(context, "字段创建成功", (await sdk.create(teamId, projectId, sheetId, payload)).data); | ||
| } catch (error) { | ||
| printError(context, error); | ||
| } | ||
| })); | ||
| registerGroupCommand("column", createCommand("update", "更新字段", async (args) => { | ||
| const flags = parseFlags(args); | ||
| const context = getContext(flags); | ||
| try { | ||
| const sheetId = requireSheetId(flags, args); | ||
| const fieldId = flags["field-id"] || args[0]; | ||
| if (!fieldId) throw new Error("缺少字段 ID,请传入 --field-id"); | ||
| const sdk = new ColumnSDK(createClient(context)); | ||
| const payload = {}; | ||
| if (flags.label || flags.title) payload.label = flags.label || flags.title; | ||
| if (flags.type) payload.type = flags.type; | ||
| printSuccess(context, "字段更新成功", (await sdk.update(sheetId, fieldId, payload)).data); | ||
| } catch (error) { | ||
| printError(context, error); | ||
| } | ||
| })); | ||
| registerGroupCommand("column", createCommand("delete", "删除字段", async (args) => { | ||
| const flags = parseFlags(args); | ||
| const context = getContext(flags); | ||
| try { | ||
| const sheetId = requireSheetId(flags, args); | ||
| const fieldId = flags["field-id"] || args[0]; | ||
| if (!fieldId) throw new Error("缺少字段 ID,请传入 --field-id"); | ||
| printSuccess(context, "字段删除成功", (await new ColumnSDK(createClient(context)).delete(sheetId, fieldId)).data); | ||
| } catch (error) { | ||
| printError(context, error); | ||
| } | ||
| })); | ||
| } | ||
| //#endregion | ||
| //#region src/commands/project/index.ts | ||
| function registerProjectCommands() { | ||
| createCommandGroup("project", "项目管理"); | ||
| registerGroupCommand("project", createCommand("list", "获取项目列表", async (args) => { | ||
| const flags = parseFlags(args); | ||
| const context = getContext(flags); | ||
| try { | ||
| const teamId = requireTeamId(context, flags); | ||
| const sdk = new ProjectSDK(createClient(context)); | ||
| const payload = { | ||
| page: Number(flags.page || "1"), | ||
| size: Number(flags.size || "20") | ||
| }; | ||
| if (flags.keyword) payload.keyword = flags.keyword; | ||
| printSuccess(context, "项目列表获取成功", (await sdk.page(teamId, payload)).data); | ||
| } catch (error) { | ||
| printError(context, error); | ||
| } | ||
| }, { | ||
| usage: "project list [--team-id <teamId>] [--page 1] [--size 20]", | ||
| examples: ["dimens-cli project list --team-id TEAM1"] | ||
| })); | ||
| registerGroupCommand("project", createCommand("info", "获取项目详情", async (args) => { | ||
| const flags = parseFlags(args); | ||
| const context = getContext(flags); | ||
| try { | ||
| const teamId = requireTeamId(context, flags); | ||
| const id = flags.id || args[0]; | ||
| if (!id) throw new Error("缺少项目 ID,请传入 --id 或 project info <id>"); | ||
| printSuccess(context, "项目详情获取成功", (await new ProjectSDK(createClient(context)).info(teamId, id)).data); | ||
| } catch (error) { | ||
| printError(context, error); | ||
| } | ||
| }, { usage: "project info --id <projectId>" })); | ||
| registerGroupCommand("project", createCommand("create", "创建项目", async (args) => { | ||
| const flags = parseFlags(args); | ||
| const context = getContext(flags); | ||
| try { | ||
| const teamId = requireTeamId(context, flags); | ||
| const name = flags.name; | ||
| if (!name) throw new Error("缺少项目名称,请传入 --name"); | ||
| const sdk = new ProjectSDK(createClient(context)); | ||
| const payload = { name }; | ||
| if (flags.remark) payload.remark = flags.remark; | ||
| printSuccess(context, "项目创建成功", (await sdk.create(teamId, payload)).data); | ||
| } catch (error) { | ||
| printError(context, error); | ||
| } | ||
| }, { usage: "project create --name <name>" })); | ||
| registerGroupCommand("project", createCommand("update", "更新项目", async (args) => { | ||
| const flags = parseFlags(args); | ||
| const context = getContext(flags); | ||
| try { | ||
| const teamId = requireTeamId(context, flags); | ||
| const id = flags.id; | ||
| if (!id) throw new Error("缺少项目 ID,请传入 --id"); | ||
| const sdk = new ProjectSDK(createClient(context)); | ||
| const payload = { id }; | ||
| if (flags.name) payload.name = flags.name; | ||
| if (flags.remark) payload.remark = flags.remark; | ||
| printSuccess(context, "项目更新成功", (await sdk.update(teamId, payload)).data); | ||
| } catch (error) { | ||
| printError(context, error); | ||
| } | ||
| }, { usage: "project update --id <projectId> [--name <name>]" })); | ||
| registerGroupCommand("project", createCommand("trash", "将项目移入回收站", async (args) => { | ||
| const flags = parseFlags(args); | ||
| const context = getContext(flags); | ||
| try { | ||
| const teamId = requireTeamId(context, flags); | ||
| const ids = (flags.ids || args.join(",")).split(",").map((item) => item.trim()).filter(Boolean); | ||
| if (ids.length === 0) throw new Error("缺少项目 ID,请传入 --ids P1,P2"); | ||
| printSuccess(context, "项目已移入回收站", (await new ProjectSDK(createClient(context)).trash(teamId, ids)).data); | ||
| } catch (error) { | ||
| printError(context, error); | ||
| } | ||
| }, { usage: "project trash --ids <id1,id2>" })); | ||
| registerGroupCommand("project", createCommand("restore", "恢复项目", async (args) => { | ||
| const flags = parseFlags(args); | ||
| const context = getContext(flags); | ||
| try { | ||
| const teamId = requireTeamId(context, flags); | ||
| const ids = (flags.ids || args.join(",")).split(",").map((item) => item.trim()).filter(Boolean); | ||
| if (ids.length === 0) throw new Error("缺少项目 ID,请传入 --ids P1,P2"); | ||
| printSuccess(context, "项目恢复成功", (await new ProjectSDK(createClient(context)).restore(teamId, ids)).data); | ||
| } catch (error) { | ||
| printError(context, error); | ||
| } | ||
| }, { usage: "project restore --ids <id1,id2>" })); | ||
| registerGroupCommand("project", createCommand("use", "设置默认项目", async (args) => { | ||
| const context = getContext(); | ||
| try { | ||
| const projectId = args[0]; | ||
| if (!projectId) throw new Error("缺少项目 ID,请传入 project use <projectId>"); | ||
| await saveProfile(mergeProfile({ projectId })); | ||
| printSuccess(context, "默认项目已切换", { projectId }); | ||
| } catch (error) { | ||
| printError(context, error); | ||
| } | ||
| }, { usage: "project use <projectId>" })); | ||
| } | ||
| //#endregion | ||
| //#region src/commands/row/index.ts | ||
| function registerRowCommands() { | ||
| createCommandGroup("row", "行数据管理"); | ||
| registerGroupCommand("row", createCommand("page", "分页获取行", async (args) => { | ||
| const flags = parseFlags(args); | ||
| const context = getContext(flags); | ||
| try { | ||
| const teamId = requireTeamId(context, flags); | ||
| const projectId = requireProjectId(context, flags); | ||
| const sheetId = requireSheetId(flags, args); | ||
| const sdk = new RowSDK(createClient(context)); | ||
| const payload = { | ||
| page: Number(flags.page || "1"), | ||
| size: Number(flags.size || "20") | ||
| }; | ||
| printSuccess(context, "行分页获取成功", (await sdk.page(teamId, projectId, sheetId, payload)).data); | ||
| } catch (error) { | ||
| printError(context, error); | ||
| } | ||
| })); | ||
| registerGroupCommand("row", createCommand("info", "获取行详情", async (args) => { | ||
| const flags = parseFlags(args); | ||
| const context = getContext(flags); | ||
| try { | ||
| const teamId = requireTeamId(context, flags); | ||
| const projectId = requireProjectId(context, flags); | ||
| const sheetId = requireSheetId(flags, args); | ||
| const rowId = flags["row-id"] || args[0]; | ||
| if (!rowId) throw new Error("缺少行 ID,请传入 --row-id"); | ||
| printSuccess(context, "行详情获取成功", (await new RowSDK(createClient(context)).info(teamId, projectId, sheetId, rowId)).data); | ||
| } catch (error) { | ||
| printError(context, error); | ||
| } | ||
| })); | ||
| registerGroupCommand("row", createCommand("create", "创建行", async (args) => { | ||
| const flags = parseFlags(args); | ||
| const context = getContext(flags); | ||
| try { | ||
| const sheetId = requireSheetId(flags, args); | ||
| const sdk = new RowSDK(createClient(context)); | ||
| const values = flags.values ? JSON.parse(flags.values) : {}; | ||
| printSuccess(context, "行创建成功", (await sdk.create(sheetId, { data: values })).data); | ||
| } catch (error) { | ||
| printError(context, error); | ||
| } | ||
| })); | ||
| registerGroupCommand("row", createCommand("update", "更新行", async (args) => { | ||
| const flags = parseFlags(args); | ||
| const context = getContext(flags); | ||
| try { | ||
| const sheetId = requireSheetId(flags, args); | ||
| const rowId = flags["row-id"] || args[0]; | ||
| if (!rowId) throw new Error("缺少行 ID,请传入 --row-id"); | ||
| const version = Number(flags.version || ""); | ||
| if (Number.isNaN(version)) throw new Error("缺少 version,请传入 --version"); | ||
| const values = flags.values ? JSON.parse(flags.values) : {}; | ||
| printSuccess(context, "行更新成功", (await new RowSDK(createClient(context)).update(sheetId, rowId, values, version)).data); | ||
| } catch (error) { | ||
| printError(context, error); | ||
| } | ||
| })); | ||
| registerGroupCommand("row", createCommand("delete", "删除行", async (args) => { | ||
| const flags = parseFlags(args); | ||
| const context = getContext(flags); | ||
| try { | ||
| const sheetId = requireSheetId(flags, args); | ||
| const rowId = flags["row-id"] || args[0]; | ||
| if (!rowId) throw new Error("缺少行 ID,请传入 --row-id"); | ||
| printSuccess(context, "行删除成功", (await new RowSDK(createClient(context)).delete(sheetId, rowId)).data); | ||
| } catch (error) { | ||
| printError(context, error); | ||
| } | ||
| })); | ||
| registerGroupCommand("row", createCommand("set-cell", "更新单元格", async (args) => { | ||
| const flags = parseFlags(args); | ||
| const context = getContext(flags); | ||
| try { | ||
| const sheetId = requireSheetId(flags, args); | ||
| const rowId = flags["row-id"]; | ||
| const fieldId = flags["field-id"] || flags["column-id"]; | ||
| if (!rowId || !fieldId) throw new Error("缺少 rowId 或 fieldId,请传入 --row-id 和 --field-id;--column-id 仅作兼容参数"); | ||
| const version = flags.version ? Number(flags.version) : void 0; | ||
| if (flags.version && Number.isNaN(version)) throw new Error("version 必须是数字,请传入 --version"); | ||
| printSuccess(context, "单元格更新成功", (await new RowSDK(createClient(context)).updateCell(sheetId, { | ||
| rowId, | ||
| fieldId, | ||
| value: flags.value, | ||
| ...version === void 0 ? {} : { version } | ||
| })).data); | ||
| } catch (error) { | ||
| printError(context, error); | ||
| } | ||
| })); | ||
| } | ||
| //#endregion | ||
| //#region src/commands/sheet/index.ts | ||
| function registerSheetCommands() { | ||
| createCommandGroup("sheet", "多维表管理"); | ||
| registerGroupCommand("sheet", createCommand("list", "获取表列表", async (args) => { | ||
| const flags = parseFlags(args); | ||
| const context = getContext(flags); | ||
| try { | ||
| const projectId = requireProjectId(context, flags); | ||
| printSuccess(context, "表列表获取成功", (await new SheetSDK(createClient(context)).list(projectId)).data); | ||
| } catch (error) { | ||
| printError(context, error); | ||
| } | ||
| })); | ||
| registerGroupCommand("sheet", createCommand("tree", "获取表树结构", async (args) => { | ||
| const flags = parseFlags(args); | ||
| const context = getContext(flags); | ||
| try { | ||
| const projectId = requireProjectId(context, flags); | ||
| printSuccess(context, "表树获取成功", (await new SheetSDK(createClient(context)).tree(projectId)).data); | ||
| } catch (error) { | ||
| printError(context, error); | ||
| } | ||
| })); | ||
| registerGroupCommand("sheet", createCommand("create", "创建表", async (args) => { | ||
| const flags = parseFlags(args); | ||
| const context = getContext(flags); | ||
| try { | ||
| const projectId = requireProjectId(context, flags); | ||
| const name = flags.name; | ||
| if (!name) throw new Error("缺少表名称,请传入 --name"); | ||
| printSuccess(context, "表创建成功", (await new SheetSDK(createClient(context)).create(projectId, { name })).data); | ||
| } catch (error) { | ||
| printError(context, error); | ||
| } | ||
| })); | ||
| registerGroupCommand("sheet", createCommand("info", "获取表详情", async (args) => { | ||
| const flags = parseFlags(args); | ||
| const context = getContext(flags); | ||
| try { | ||
| const teamId = requireTeamId(context, flags); | ||
| const projectId = requireProjectId(context, flags); | ||
| const sheetId = requireSheetId(flags, args); | ||
| printSuccess(context, "表详情获取成功", (await new SheetSDK(createClient(context)).info(teamId, projectId, sheetId)).data); | ||
| } catch (error) { | ||
| printError(context, error); | ||
| } | ||
| })); | ||
| registerGroupCommand("sheet", createCommand("update", "更新表", async (args) => { | ||
| const flags = parseFlags(args); | ||
| const context = getContext(flags); | ||
| try { | ||
| const teamId = requireTeamId(context, flags); | ||
| const projectId = requireProjectId(context, flags); | ||
| const sheetId = requireSheetId(flags, args); | ||
| const sdk = new SheetSDK(createClient(context)); | ||
| const payload = {}; | ||
| if (flags.name) payload.name = flags.name; | ||
| printSuccess(context, "表更新成功", (await sdk.update(teamId, projectId, sheetId, payload)).data); | ||
| } catch (error) { | ||
| printError(context, error); | ||
| } | ||
| })); | ||
| registerGroupCommand("sheet", createCommand("delete", "删除表", async (args) => { | ||
| const flags = parseFlags(args); | ||
| const context = getContext(flags); | ||
| try { | ||
| const teamId = requireTeamId(context, flags); | ||
| const projectId = requireProjectId(context, flags); | ||
| const sheetId = requireSheetId(flags, args); | ||
| printSuccess(context, "表删除成功", (await new SheetSDK(createClient(context)).delete(teamId, projectId, sheetId)).data); | ||
| } catch (error) { | ||
| printError(context, error); | ||
| } | ||
| })); | ||
| registerGroupCommand("sheet", createCommand("structure", "获取表结构", async (args) => { | ||
| const flags = parseFlags(args); | ||
| const context = getContext(flags); | ||
| try { | ||
| const sheetId = requireSheetId(flags, args); | ||
| printSuccess(context, "表结构获取成功", (await new SheetSDK(createClient(context)).structure(sheetId)).data); | ||
| } catch (error) { | ||
| printError(context, error); | ||
| } | ||
| })); | ||
| } | ||
| //#endregion | ||
| //#region src/commands/skill/index.ts | ||
| function requireSkillName(args) { | ||
| const skillName = args[0]; | ||
| if (!skillName) throw new Error("缺少技能名称,请传入 skill info <name> 或 skill show <name>"); | ||
| return skillName; | ||
| } | ||
| function getSkillOrThrow(name) { | ||
| const skill = getSkill(name); | ||
| if (!skill) throw new Error(`未找到技能: ${name}`); | ||
| return skill; | ||
| } | ||
| function toRelativeSkillPath(filePath) { | ||
| return relative(getSkillsRootPath(), filePath) || filePath; | ||
| } | ||
| function printList(title, items) { | ||
| console.log(`${title}:`); | ||
| if (!items || items.length === 0) { | ||
| console.log(" (无)"); | ||
| return; | ||
| } | ||
| items.forEach((item) => { | ||
| console.log(` - ${item}`); | ||
| }); | ||
| } | ||
| function normalizeSkillForOutput(skill) { | ||
| return { | ||
| ...skill, | ||
| recommendExamples: getRecommendExamples(skill.name), | ||
| skillPath: skill.skillPath ? toRelativeSkillPath(skill.skillPath) : void 0, | ||
| referencesDir: skill.referencesDir ? toRelativeSkillPath(skill.referencesDir) : void 0, | ||
| references: skill.references?.map((reference) => toRelativeSkillPath(reference)) ?? [] | ||
| }; | ||
| } | ||
| function printMapping(skill) { | ||
| printList("命令组", skill.commandGroups); | ||
| printList("命令", skill.commands); | ||
| printList("SDK", skill.sdkModules); | ||
| printList("工具", skill.toolNames); | ||
| } | ||
| const SKILL_RECOMMEND_EXAMPLES = { | ||
| "dimens-system-orchestrator": [ | ||
| "帮我生成一个客户管理系统", | ||
| "帮我做一个项目管理平台", | ||
| "生成一个审批系统" | ||
| ], | ||
| "dimens-workflow": [ | ||
| "工作流 默认模型 AI 分析", | ||
| "审批流程 自动化", | ||
| "flow chat completions" | ||
| ], | ||
| "dimens-key-auth": [ | ||
| "api-key token", | ||
| "api secret 登录", | ||
| "第三方鉴权接入" | ||
| ], | ||
| "dimens-team": [ | ||
| "团队 项目 成员", | ||
| "teamId projectId", | ||
| "租户隔离 项目上下文" | ||
| ], | ||
| "dimens-table": [ | ||
| "多维表格 字段 row", | ||
| "sheet column view", | ||
| "字段类型 系统视图" | ||
| ], | ||
| "dimens-permission": [ | ||
| "行级权限 公开访问 只读", | ||
| "列权限 协同越权", | ||
| "acl 权限" | ||
| ], | ||
| "dimens-report": [ | ||
| "报表 图表 参数筛选", | ||
| "dashboard 数据源", | ||
| "统计看板 导出" | ||
| ] | ||
| }; | ||
| function getRecommendExamples(skillName) { | ||
| return SKILL_RECOMMEND_EXAMPLES[skillName] ?? []; | ||
| } | ||
| function getRecommendQuery(args) { | ||
| const queryParts = []; | ||
| for (let index = 0; index < args.length; index += 1) { | ||
| const current = args[index]; | ||
| if (!current) continue; | ||
| if (current.startsWith("--")) { | ||
| const next = args[index + 1]; | ||
| if (next && !next.startsWith("--")) index += 1; | ||
| continue; | ||
| } | ||
| queryParts.push(current); | ||
| } | ||
| return queryParts.join(" ").trim(); | ||
| } | ||
| const SYSTEM_BUILD_VERBS = [ | ||
| "生成", | ||
| "新建", | ||
| "创建", | ||
| "做", | ||
| "搭建", | ||
| "搭", | ||
| "构建", | ||
| "开发" | ||
| ]; | ||
| const SYSTEM_BUILD_TARGETS = [ | ||
| "系统", | ||
| "平台", | ||
| "管理系统", | ||
| "业务系统", | ||
| "crm", | ||
| "客户管理", | ||
| "项目管理", | ||
| "售后管理", | ||
| "审批系统" | ||
| ]; | ||
| const WORKFLOW_INTENT_KEYWORDS = [ | ||
| "工作流", | ||
| "workflow", | ||
| "flow", | ||
| "默认模型", | ||
| "ai 分析", | ||
| "审批流程", | ||
| "自动化" | ||
| ]; | ||
| const AUTH_INTENT_KEYWORDS = [ | ||
| "api-key", | ||
| "apikey", | ||
| "api key", | ||
| "api-secret", | ||
| "apisecret", | ||
| "api secret", | ||
| "token", | ||
| "登录", | ||
| "鉴权" | ||
| ]; | ||
| const TABLE_INTENT_KEYWORDS = [ | ||
| "多维表格", | ||
| "sheet", | ||
| "row", | ||
| "column", | ||
| "字段", | ||
| "视图", | ||
| "table" | ||
| ]; | ||
| const PERMISSION_INTENT_KEYWORDS = [ | ||
| "权限", | ||
| "行级权限", | ||
| "列权限", | ||
| "公开访问", | ||
| "只读", | ||
| "acl", | ||
| "协同越权" | ||
| ]; | ||
| const REPORT_INTENT_KEYWORDS = [ | ||
| "报表", | ||
| "图表", | ||
| "dashboard", | ||
| "参数筛选", | ||
| "数据源", | ||
| "统计", | ||
| "看板" | ||
| ]; | ||
| function getSystemOrchestratorBonus(skill, normalizedQuery) { | ||
| if (skill.name !== "dimens-system-orchestrator") return 0; | ||
| const hasBuildVerb = SYSTEM_BUILD_VERBS.some((keyword) => normalizedQuery.includes(keyword)); | ||
| const matchedTargets = SYSTEM_BUILD_TARGETS.filter((keyword) => normalizedQuery.includes(keyword)); | ||
| let score = 0; | ||
| if (hasBuildVerb && matchedTargets.length > 0) score += 10; | ||
| score += matchedTargets.length * 4; | ||
| return score; | ||
| } | ||
| function hasIntentKeyword(normalizedQuery, keywords) { | ||
| return keywords.some((keyword) => normalizedQuery.includes(keyword)); | ||
| } | ||
| function getSkillMatchSignals(skill, query) { | ||
| const normalizedQuery = query.toLowerCase(); | ||
| const haystacks = [ | ||
| skill.name, | ||
| skill.description, | ||
| ...skill.tags ?? [], | ||
| ...skill.commandGroups ?? [], | ||
| ...skill.commands ?? [], | ||
| ...skill.sdkModules ?? [], | ||
| ...skill.toolNames ?? [] | ||
| ].join("\n").toLowerCase(); | ||
| const compactQuery = normalizedQuery.replace(/\s+/g, ""); | ||
| const keywords = normalizedQuery.split(/\s+/).map((item) => item.trim()).filter(Boolean); | ||
| let keywordScore = 0; | ||
| const matchedBy = []; | ||
| keywords.forEach((keyword) => { | ||
| if (!keyword) return; | ||
| if (skill.name.toLowerCase().includes(keyword)) { | ||
| keywordScore += 4; | ||
| if (!matchedBy.includes("name-keyword")) matchedBy.push("name-keyword"); | ||
| return; | ||
| } | ||
| if (haystacks.includes(keyword)) { | ||
| keywordScore += 1; | ||
| if (!matchedBy.includes("context-keyword")) matchedBy.push("context-keyword"); | ||
| } | ||
| }); | ||
| let phraseScore = 0; | ||
| if (compactQuery && compactQuery !== normalizedQuery && haystacks.includes(compactQuery)) phraseScore += 2; | ||
| if (compactQuery && haystacks.includes(compactQuery)) phraseScore += 2; | ||
| if (phraseScore > 0 && !matchedBy.includes("compact-phrase")) matchedBy.push("compact-phrase"); | ||
| const systemBonus = getSystemOrchestratorBonus(skill, normalizedQuery); | ||
| if (systemBonus > 0) matchedBy.push("system-build-intent"); | ||
| if (skill.name === "dimens-workflow" && hasIntentKeyword(normalizedQuery, WORKFLOW_INTENT_KEYWORDS)) matchedBy.push("workflow-intent"); | ||
| if (skill.name === "dimens-key-auth" && hasIntentKeyword(normalizedQuery, AUTH_INTENT_KEYWORDS)) matchedBy.push("auth-intent"); | ||
| if (skill.name === "dimens-table" && hasIntentKeyword(normalizedQuery, TABLE_INTENT_KEYWORDS)) matchedBy.push("table-intent"); | ||
| if (skill.name === "dimens-permission" && hasIntentKeyword(normalizedQuery, PERMISSION_INTENT_KEYWORDS)) matchedBy.push("permission-intent"); | ||
| if (skill.name === "dimens-report" && hasIntentKeyword(normalizedQuery, REPORT_INTENT_KEYWORDS)) matchedBy.push("report-intent"); | ||
| const score = keywordScore + phraseScore + systemBonus; | ||
| const reasonParts = []; | ||
| if (systemBonus > 0) reasonParts.push("命中系统建设意图"); | ||
| if (matchedBy.includes("workflow-intent")) reasonParts.push("命中工作流意图"); | ||
| if (matchedBy.includes("auth-intent")) reasonParts.push("命中鉴权接入意图"); | ||
| if (matchedBy.includes("table-intent")) reasonParts.push("命中多维表格意图"); | ||
| if (matchedBy.includes("permission-intent")) reasonParts.push("命中权限意图"); | ||
| if (matchedBy.includes("report-intent")) reasonParts.push("命中报表意图"); | ||
| if (matchedBy.includes("name-keyword")) reasonParts.push("匹配到技能名关键词"); | ||
| if (matchedBy.includes("context-keyword")) reasonParts.push("匹配到描述或映射关键词"); | ||
| if (matchedBy.includes("compact-phrase")) reasonParts.push("匹配到紧凑短语"); | ||
| return { | ||
| score, | ||
| matchedBy, | ||
| reason: reasonParts.join(";") || "基于关键词相关性匹配" | ||
| }; | ||
| } | ||
| function registerSkillCommands() { | ||
| createCommandGroup("skill", "技能查看与提示语文档"); | ||
| registerGroupCommand("skill", createCommand("list", "列出所有已发现的技能", async (args) => { | ||
| const context = getContext(parseFlags(args)); | ||
| try { | ||
| const skills = getAllSkills(); | ||
| if (context.output === "json") { | ||
| console.log(formatSuccess("技能列表获取成功", skills.map((skill) => normalizeSkillForOutput(skill)), context.output)); | ||
| return; | ||
| } | ||
| console.log("\n已发现技能:\n"); | ||
| skills.forEach((skill) => { | ||
| console.log(`- ${skill.name}`); | ||
| console.log(` ${skill.description.split("\n")[0] ?? skill.description}`); | ||
| }); | ||
| console.log(""); | ||
| } catch (error) { | ||
| printError(context, error); | ||
| } | ||
| }, { | ||
| usage: "skill list", | ||
| examples: ["dimens-cli skill list"] | ||
| })); | ||
| registerGroupCommand("skill", createCommand("info", "查看技能元信息", async (args) => { | ||
| const context = getContext(parseFlags(args)); | ||
| try { | ||
| const skill = getSkillOrThrow(requireSkillName(args)); | ||
| const normalizedSkill = normalizeSkillForOutput(skill); | ||
| if (context.output === "json") { | ||
| console.log(formatSuccess("技能信息获取成功", normalizedSkill, context.output)); | ||
| return; | ||
| } | ||
| console.log(`\n技能: ${skill.name}`); | ||
| console.log(`描述: ${skill.description.split("\n")[0] ?? skill.description}`); | ||
| if (skill.skillPath) console.log(`主文件: ${toRelativeSkillPath(skill.skillPath)}`); | ||
| if (skill.referencesDir) console.log(`参考目录: ${toRelativeSkillPath(skill.referencesDir)}`); | ||
| printMapping(skill); | ||
| printList("推荐关键词示例", getRecommendExamples(skill.name)); | ||
| printList("references", skill.references?.map((reference) => toRelativeSkillPath(reference))); | ||
| console.log(""); | ||
| } catch (error) { | ||
| printError(context, error); | ||
| } | ||
| }, { | ||
| usage: "skill info <name>", | ||
| examples: ["dimens-cli skill info dimens-table"] | ||
| })); | ||
| registerGroupCommand("skill", createCommand("recommend", "根据文本或关键词推荐相关技能", async (args) => { | ||
| const context = getContext(parseFlags(args)); | ||
| try { | ||
| const query = getRecommendQuery(args); | ||
| if (!query) throw new Error("缺少推荐文本,请传入 skill recommend <text>"); | ||
| const rankedSkills = getAllSkills().map((skill) => ({ | ||
| skill, | ||
| ...getSkillMatchSignals(skill, query) | ||
| })).filter((item) => item.score > 0).sort((a, b) => b.score - a.score || a.skill.name.localeCompare(b.skill.name, "zh-CN")); | ||
| if (context.output === "json") { | ||
| console.log(formatSuccess("技能推荐完成", rankedSkills.map((item) => ({ | ||
| score: item.score, | ||
| matchedBy: item.matchedBy, | ||
| reason: item.reason, | ||
| skill: normalizeSkillForOutput(item.skill) | ||
| })), context.output)); | ||
| return; | ||
| } | ||
| console.log(`\n推荐 Skill(query: ${query}):\n`); | ||
| if (rankedSkills.length === 0) { | ||
| console.log("(无匹配结果)\n"); | ||
| return; | ||
| } | ||
| rankedSkills.forEach((item) => { | ||
| console.log(`- ${item.skill.name} (score: ${item.score})`); | ||
| console.log(` ${item.skill.description.split("\n")[0] ?? item.skill.description}`); | ||
| }); | ||
| console.log(""); | ||
| } catch (error) { | ||
| printError(context, error); | ||
| } | ||
| }, { | ||
| usage: "skill recommend <text>", | ||
| examples: ["dimens-cli skill recommend 工作流 默认模型 AI 分析", "dimens-cli skill recommend api-key token --output json"] | ||
| })); | ||
| registerGroupCommand("skill", createCommand("show", "显示技能文档内容", async (args) => { | ||
| const flags = parseFlags(args); | ||
| const context = getContext(flags); | ||
| try { | ||
| const skillName = requireSkillName(args.filter((arg) => !arg.startsWith("--"))); | ||
| const skill = getSkillOrThrow(skillName); | ||
| const normalizedSkill = normalizeSkillForOutput(skill); | ||
| if (!skill.skillPath) throw new Error(`技能 ${skillName} 缺少主文件路径`); | ||
| const mainOnly = flags["main-only"] === "true"; | ||
| const referencesOnly = flags["references-only"] === "true"; | ||
| const mappingOnly = flags["mapping-only"] === "true"; | ||
| const includeReferences = flags.references === "true" || referencesOnly; | ||
| if (context.output === "json") { | ||
| const payload = { skill: normalizedSkill }; | ||
| if (!referencesOnly && !mappingOnly) payload.main = readFileSync(skill.skillPath, "utf8"); | ||
| if (!mainOnly && !mappingOnly && skill.references && skill.references.length > 0) payload.references = skill.references.map((reference) => ({ | ||
| path: toRelativeSkillPath(reference), | ||
| content: readFileSync(reference, "utf8") | ||
| })); | ||
| if (!mainOnly && !referencesOnly) payload.mapping = { | ||
| commandGroups: skill.commandGroups ?? [], | ||
| commands: skill.commands ?? [], | ||
| sdkModules: skill.sdkModules ?? [], | ||
| toolNames: skill.toolNames ?? [] | ||
| }; | ||
| console.log(formatSuccess("技能文档获取成功", payload, context.output)); | ||
| return; | ||
| } | ||
| if (!referencesOnly && !mappingOnly) { | ||
| console.log(`\n===== ${skill.name} / ${toRelativeSkillPath(skill.skillPath)} =====\n`); | ||
| console.log(readFileSync(skill.skillPath, "utf8")); | ||
| } | ||
| if (!mainOnly && !referencesOnly) { | ||
| console.log(`\n===== ${skill.name} / mapping =====\n`); | ||
| printMapping(skill); | ||
| } | ||
| if (!mainOnly && !mappingOnly && includeReferences && skill.references && skill.references.length > 0) skill.references.forEach((reference) => { | ||
| console.log(`\n===== ${toRelativeSkillPath(reference)} =====\n`); | ||
| console.log(readFileSync(reference, "utf8")); | ||
| }); | ||
| console.log(""); | ||
| } catch (error) { | ||
| printError(context, error); | ||
| } | ||
| }, { | ||
| usage: "skill show <name> [--references] [--main-only] [--references-only] [--mapping-only]", | ||
| examples: [ | ||
| "dimens-cli skill show dimens-workflow", | ||
| "dimens-cli skill show dimens-workflow --references", | ||
| "dimens-cli skill show dimens-table --mapping-only", | ||
| "dimens-cli skill show dimens-key-auth --output json" | ||
| ] | ||
| })); | ||
| } | ||
| //#endregion | ||
| //#region src/commands/index.ts | ||
| var commands_exports = /* @__PURE__ */ __exportAll({ registerCommands: () => registerCommands }); | ||
| function registerCommands() { | ||
| logger.info("开始注册所有命令..."); | ||
| createCommandGroup("system", "系统命令"); | ||
| registerHelpCommand(); | ||
| registerVersionCommand(); | ||
| registerAuthCommands(); | ||
| registerSkillCommands(); | ||
| registerProjectCommands(); | ||
| registerSheetCommands(); | ||
| registerColumnCommands(); | ||
| registerRowCommands(); | ||
| registerAICommands(); | ||
| logger.info("所有命令注册完成"); | ||
| } | ||
| //#endregion | ||
| export { config as _, getRelatedSkillObjectsForExecutionContext as a, getAllSkills as c, clearCommands as d, getAllCommands as f, registerCommand as g, getGroupCommand as h, clearExecutionContext as i, getSkill as l, getCommandGroup as m, registerCommands as n, setExecutionContext as o, getCommand as p, parseFlags as r, SKILLS as s, commands_exports as t, getSkillsRootPath as u }; | ||
| //# sourceMappingURL=commands-DhXU3rGj.mjs.map |
Sorry, the diff of this file is too big to display
| import { t as __exportAll } from "./rolldown-runtime-95iHPtFO.mjs"; | ||
| import { a as AuthSDK, i as ColumnSDK, n as RowSDK, o as DimensClient, r as ProjectSDK, s as FlowChatSDK, t as SheetSDK } from "./sheet-jiBqJC3e.mjs"; | ||
| //#region src/sdk/index.ts | ||
| var sdk_exports = /* @__PURE__ */ __exportAll({ | ||
| DimensSDK: () => DimensSDK, | ||
| createSDK: () => createSDK | ||
| }); | ||
| var DimensSDK = class { | ||
| client; | ||
| auth; | ||
| project; | ||
| sheet; | ||
| column; | ||
| row; | ||
| ai; | ||
| constructor(config) { | ||
| this.client = new DimensClient(config); | ||
| this.auth = new AuthSDK(this.client); | ||
| this.project = new ProjectSDK(this.client); | ||
| this.sheet = new SheetSDK(this.client); | ||
| this.column = new ColumnSDK(this.client); | ||
| this.row = new RowSDK(this.client); | ||
| this.ai = new FlowChatSDK(this.client); | ||
| } | ||
| }; | ||
| function createSDK(config) { | ||
| return new DimensSDK(config); | ||
| } | ||
| //#endregion | ||
| export { createSDK as n, sdk_exports as r, DimensSDK as t }; | ||
| //# sourceMappingURL=sdk-DAD4AM5p.mjs.map |
| {"version":3,"file":"sdk-DAD4AM5p.mjs","names":[],"sources":["../src/sdk/index.ts"],"sourcesContent":["import { AuthSDK } from './auth';\nimport { DimensClient, type APIResponse, type DimensClientOptions } from './client';\nimport { ColumnSDK } from './column';\nimport { FlowChatSDK } from './flow-chat';\nimport { ProjectSDK } from './project';\nimport { RowSDK } from './row';\nimport { SheetSDK } from './sheet';\n\nexport type { APIResponse, DimensClientOptions };\n\nexport interface SDKConfig extends DimensClientOptions {}\n\nexport class DimensSDK {\n readonly client: DimensClient;\n readonly auth: AuthSDK;\n readonly project: ProjectSDK;\n readonly sheet: SheetSDK;\n readonly column: ColumnSDK;\n readonly row: RowSDK;\n readonly ai: FlowChatSDK;\n\n constructor(config: SDKConfig) {\n this.client = new DimensClient(config);\n this.auth = new AuthSDK(this.client);\n this.project = new ProjectSDK(this.client);\n this.sheet = new SheetSDK(this.client);\n this.column = new ColumnSDK(this.client);\n this.row = new RowSDK(this.client);\n this.ai = new FlowChatSDK(this.client);\n }\n}\n\nexport function createSDK(config: SDKConfig): DimensSDK {\n return new DimensSDK(config);\n}\n\nexport { DimensClient } from './client';\nexport { AuthSDK } from './auth';\nexport { ProjectSDK } from './project';\nexport { SheetSDK } from './sheet';\nexport { ColumnSDK } from './column';\nexport { RowSDK } from './row';\nexport { FlowChatSDK } from './flow-chat';\n"],"mappings":";;;;;;;;AAYA,IAAa,YAAb,MAAuB;CACrB,AAAS;CACT,AAAS;CACT,AAAS;CACT,AAAS;CACT,AAAS;CACT,AAAS;CACT,AAAS;CAET,YAAY,QAAmB;AAC7B,OAAK,SAAS,IAAI,aAAa,OAAO;AACtC,OAAK,OAAO,IAAI,QAAQ,KAAK,OAAO;AACpC,OAAK,UAAU,IAAI,WAAW,KAAK,OAAO;AAC1C,OAAK,QAAQ,IAAI,SAAS,KAAK,OAAO;AACtC,OAAK,SAAS,IAAI,UAAU,KAAK,OAAO;AACxC,OAAK,MAAM,IAAI,OAAO,KAAK,OAAO;AAClC,OAAK,KAAK,IAAI,YAAY,KAAK,OAAO;;;AAI1C,SAAgB,UAAU,QAA8B;AACtD,QAAO,IAAI,UAAU,OAAO"} |
| import { dirname, join } from "path"; | ||
| import { readFileSync } from "fs"; | ||
| import { fileURLToPath } from "url"; | ||
| //#region src/core/version.ts | ||
| /** | ||
| * 版本信息 | ||
| */ | ||
| let _version; | ||
| function getVersion() { | ||
| if (_version) return _version; | ||
| try { | ||
| const packageJsonPath = join(dirname(fileURLToPath(import.meta.url)), "..", "..", "package.json"); | ||
| _version = JSON.parse(readFileSync(packageJsonPath, "utf-8")).version; | ||
| } catch { | ||
| _version = "1.0.0"; | ||
| } | ||
| return _version ?? "1.0.0"; | ||
| } | ||
| const version = getVersion(); | ||
| function getUserAgent() { | ||
| return `DimensCLI/${version} (Node.js/${process.version})`; | ||
| } | ||
| //#endregion | ||
| //#region src/sdk/flow-chat.ts | ||
| var FlowChatSDK = class { | ||
| constructor(client) { | ||
| this.client = client; | ||
| } | ||
| completions(teamId, payload) { | ||
| return this.client.post(`/app/flow/${teamId}/v1/chat/completions`, payload); | ||
| } | ||
| }; | ||
| //#endregion | ||
| //#region src/core/http.ts | ||
| async function requestJson(url, init = {}) { | ||
| const response = await fetch(url, init); | ||
| const payload = await response.json(); | ||
| if (!response.ok) throw new Error(payload?.message || `HTTP ${response.status}`); | ||
| return payload; | ||
| } | ||
| //#endregion | ||
| //#region src/sdk/client.ts | ||
| var DimensClient = class { | ||
| options; | ||
| constructor(options) { | ||
| this.options = options; | ||
| } | ||
| getOptions() { | ||
| return { ...this.options }; | ||
| } | ||
| async get(path, query, init = {}) { | ||
| return requestJson(this.buildUrl(path, query), { | ||
| ...init, | ||
| method: "GET", | ||
| headers: this.buildHeaders(init.headers) | ||
| }); | ||
| } | ||
| async post(path, body, init = {}) { | ||
| const requestInit = { | ||
| ...init, | ||
| method: "POST", | ||
| headers: this.buildHeaders(init.headers, true) | ||
| }; | ||
| if (body !== void 0) requestInit.body = JSON.stringify(body); | ||
| return requestJson(this.buildUrl(path), requestInit); | ||
| } | ||
| buildUrl(path, query) { | ||
| const base = this.options.baseUrl.replace(/\/+$/, ""); | ||
| const normalizedPath = path.startsWith("/") ? path : `/${path}`; | ||
| const url = new URL(`${base}${normalizedPath}`); | ||
| Object.entries(query || {}).forEach(([key, value]) => { | ||
| if (value === void 0 || value === null || value === "") return; | ||
| url.searchParams.set(key, String(value)); | ||
| }); | ||
| return url.toString(); | ||
| } | ||
| buildHeaders(headers, hasJsonBody = false) { | ||
| const merged = normalizeHeaders(headers); | ||
| merged.Accept = "application/json"; | ||
| merged["User-Agent"] = getUserAgent(); | ||
| if (hasJsonBody) merged["Content-Type"] = "application/json"; | ||
| if (this.options.token) merged.Authorization = `Bearer ${this.options.token}`; | ||
| if (this.options.refreshToken) merged["X-Refresh-Token"] = this.options.refreshToken; | ||
| return merged; | ||
| } | ||
| }; | ||
| function normalizeHeaders(headers) { | ||
| if (!headers) return {}; | ||
| if (typeof Headers !== "undefined" && headers instanceof Headers) return Object.fromEntries(headers.entries()); | ||
| if (Array.isArray(headers)) return Object.fromEntries(headers.map(([key, value]) => [String(key), String(value)])); | ||
| const normalized = {}; | ||
| Object.entries(headers).forEach(([key, value]) => { | ||
| normalized[key] = typeof value === "string" ? value : value.join(", "); | ||
| }); | ||
| return normalized; | ||
| } | ||
| //#endregion | ||
| //#region src/sdk/auth.ts | ||
| var AuthSDK = class { | ||
| constructor(client) { | ||
| this.client = client; | ||
| } | ||
| login(payload) { | ||
| return this.client.post("/login", payload); | ||
| } | ||
| loginByApiKey(payload) { | ||
| return this.client.post("/open/user/login/apiKey", payload); | ||
| } | ||
| exchangeTokenByApiKey(payload) { | ||
| return this.loginByApiKey(payload); | ||
| } | ||
| refreshToken() { | ||
| return this.client.get("/refreshToken"); | ||
| } | ||
| }; | ||
| //#endregion | ||
| //#region src/sdk/column.ts | ||
| var ColumnSDK = class { | ||
| constructor(client) { | ||
| this.client = client; | ||
| } | ||
| list(teamId, projectId, sheetId) { | ||
| return this.client.get(`/app/mul/${teamId}/${projectId}/sheet/${sheetId}/column/list`); | ||
| } | ||
| create(teamId, projectId, sheetId, payload) { | ||
| return this.client.post(`/app/mul/${teamId}/${projectId}/sheet/${sheetId}/column/create`, payload); | ||
| } | ||
| update(sheetId, fieldId, payload) { | ||
| return this.client.post(`/app/mul/sheet/${sheetId}/column/${fieldId}/update`, payload); | ||
| } | ||
| delete(sheetId, fieldId) { | ||
| return this.client.post(`/app/mul/sheet/${sheetId}/column/${fieldId}/delete`); | ||
| } | ||
| }; | ||
| //#endregion | ||
| //#region src/sdk/project.ts | ||
| var ProjectSDK = class { | ||
| constructor(client) { | ||
| this.client = client; | ||
| } | ||
| page(teamId, payload) { | ||
| return this.client.post(`/app/org/${teamId}/project/page`, payload); | ||
| } | ||
| info(teamId, id) { | ||
| return this.client.get(`/app/org/${teamId}/project/info`, { id }); | ||
| } | ||
| create(teamId, payload) { | ||
| return this.client.post(`/app/org/${teamId}/project/add`, payload); | ||
| } | ||
| update(teamId, payload) { | ||
| return this.client.post(`/app/org/${teamId}/project/update`, payload); | ||
| } | ||
| trash(teamId, ids) { | ||
| return this.client.post(`/app/org/${teamId}/project/trash`, { ids }); | ||
| } | ||
| restore(teamId, ids) { | ||
| return this.client.post(`/app/org/${teamId}/project/restore`, { ids }); | ||
| } | ||
| }; | ||
| //#endregion | ||
| //#region src/sdk/row.ts | ||
| var RowSDK = class { | ||
| constructor(client) { | ||
| this.client = client; | ||
| } | ||
| page(teamId, projectId, sheetId, payload) { | ||
| return this.client.post(`/app/mul/${teamId}/${projectId}/sheet/${sheetId}/row/page`, payload); | ||
| } | ||
| info(teamId, projectId, sheetId, rowId) { | ||
| return this.client.get(`/app/mul/${teamId}/${projectId}/sheet/${sheetId}/row/${rowId}/info`); | ||
| } | ||
| create(sheetId, payload) { | ||
| return this.client.post(`/app/mul/sheet/${sheetId}/row/create`, payload); | ||
| } | ||
| update(sheetId, rowId, data, version) { | ||
| return this.client.post(`/app/mul/sheet/${sheetId}/row/${rowId}/update`, { | ||
| data, | ||
| version | ||
| }); | ||
| } | ||
| delete(sheetId, rowId) { | ||
| return this.client.post(`/app/mul/sheet/${sheetId}/row/${rowId}/delete`); | ||
| } | ||
| updateCell(sheetId, payload) { | ||
| return this.client.post(`/app/mul/sheet/${sheetId}/row/cell`, payload); | ||
| } | ||
| }; | ||
| //#endregion | ||
| //#region src/sdk/sheet.ts | ||
| var SheetSDK = class { | ||
| constructor(client) { | ||
| this.client = client; | ||
| } | ||
| list(projectId) { | ||
| return this.client.get(`/app/mul/project/${projectId}/sheet/list`); | ||
| } | ||
| tree(projectId) { | ||
| return this.client.get(`/app/mul/project/${projectId}/sheet/tree`); | ||
| } | ||
| create(projectId, payload) { | ||
| return this.client.post(`/app/mul/project/${projectId}/sheet/create`, payload); | ||
| } | ||
| info(teamId, projectId, sheetId) { | ||
| return this.client.get(`/app/mul/${teamId}/${projectId}/sheet/${sheetId}/info`); | ||
| } | ||
| update(teamId, projectId, sheetId, payload) { | ||
| return this.client.post(`/app/mul/${teamId}/${projectId}/sheet/${sheetId}/update`, payload); | ||
| } | ||
| delete(teamId, projectId, sheetId) { | ||
| return this.client.post(`/app/mul/${teamId}/${projectId}/sheet/${sheetId}/delete`); | ||
| } | ||
| structure(sheetId) { | ||
| return this.client.get(`/app/mul/sheet/${sheetId}/structure`); | ||
| } | ||
| }; | ||
| //#endregion | ||
| export { AuthSDK as a, getUserAgent as c, ColumnSDK as i, getVersion as l, RowSDK as n, DimensClient as o, ProjectSDK as r, FlowChatSDK as s, SheetSDK as t, version as u }; | ||
| //# sourceMappingURL=sheet-jiBqJC3e.mjs.map |
| {"version":3,"file":"sheet-jiBqJC3e.mjs","names":[],"sources":["../src/core/version.ts","../src/sdk/flow-chat.ts","../src/core/http.ts","../src/sdk/client.ts","../src/sdk/auth.ts","../src/sdk/column.ts","../src/sdk/project.ts","../src/sdk/row.ts","../src/sdk/sheet.ts"],"sourcesContent":["/**\n * 版本信息\n */\n\nimport { readFileSync } from 'fs';\nimport { join } from 'path';\nimport { fileURLToPath } from 'url';\nimport { dirname } from 'path';\n\nlet _version: string | undefined;\n\nexport function getVersion(): string {\n if (_version) return _version;\n\n try {\n const __filename = fileURLToPath(import.meta.url);\n const __dirname = dirname(__filename);\n const packageJsonPath = join(__dirname, '..', '..', 'package.json');\n const packageJson = JSON.parse(readFileSync(packageJsonPath, 'utf-8'));\n _version = packageJson.version;\n } catch {\n _version = '1.0.0';\n }\n\n return _version ?? '1.0.0';\n}\n\nexport const version = getVersion();\n\nexport function getUserAgent(): string {\n return `DimensCLI/${version} (Node.js/${process.version})`;\n}\n","import type { APIResponse } from './client';\nimport { DimensClient } from './client';\n\nexport interface FlowChatMessage {\n role: 'system' | 'user' | 'assistant';\n content: string;\n}\n\nexport interface FlowChatCompletionsPayload {\n model?: string | number;\n messages: FlowChatMessage[];\n stream?: boolean;\n user?: string;\n sessionId?: string;\n [key: string]: unknown;\n}\n\nexport interface FlowChatCompletionChoice {\n index?: number;\n message: {\n role: string;\n content: string;\n };\n finish_reason?: string | null;\n}\n\nexport interface FlowChatCompletionResult {\n id: string;\n object?: string;\n created?: number;\n model?: string;\n choices: FlowChatCompletionChoice[];\n usage?: Record<string, unknown>;\n}\n\nexport class FlowChatSDK {\n constructor(private readonly client: DimensClient) {}\n\n completions(\n teamId: string,\n payload: FlowChatCompletionsPayload\n ): Promise<APIResponse<FlowChatCompletionResult>> {\n return this.client.post<FlowChatCompletionResult>(\n `/app/flow/${teamId}/v1/chat/completions`,\n payload\n );\n }\n}\n","export async function requestJson<T>(\n url: string,\n init: RequestInit = {}\n): Promise<T> {\n const response = await fetch(url, init);\n const payload = (await response.json()) as { message?: string };\n\n if (!response.ok) {\n throw new Error(payload?.message || `HTTP ${response.status}`);\n }\n\n return payload as T;\n}\n","import { getUserAgent } from '../core/version';\nimport { requestJson } from '../core/http';\n\nexport interface DimensClientOptions {\n baseUrl: string;\n token?: string;\n refreshToken?: string;\n teamId?: string;\n projectId?: string;\n}\n\nexport interface APIResponse<T> {\n code: number;\n message: string;\n data: T;\n}\n\ntype QueryValue = string | number | boolean | null | undefined;\ntype QueryParams = Record<string, QueryValue>;\ntype HeaderTupleList = Array<[string, string]> | string[][];\ntype HeaderObjectInput = Record<string, string | readonly string[]>;\n\nexport class DimensClient {\n private readonly options: DimensClientOptions;\n\n constructor(options: DimensClientOptions) {\n this.options = options;\n }\n\n getOptions(): DimensClientOptions {\n return { ...this.options };\n }\n\n async get<T>(\n path: string,\n query?: QueryParams,\n init: RequestInit = {}\n ): Promise<APIResponse<T>> {\n return requestJson<APIResponse<T>>(this.buildUrl(path, query), {\n ...init,\n method: 'GET',\n headers: this.buildHeaders(init.headers),\n });\n }\n\n async post<T>(\n path: string,\n body?: unknown,\n init: RequestInit = {}\n ): Promise<APIResponse<T>> {\n const requestInit: RequestInit = {\n ...init,\n method: 'POST',\n headers: this.buildHeaders(init.headers, true),\n };\n\n if (body !== undefined) {\n requestInit.body = JSON.stringify(body);\n }\n\n return requestJson<APIResponse<T>>(this.buildUrl(path), requestInit);\n }\n\n private buildUrl(path: string, query?: QueryParams): string {\n const base = this.options.baseUrl.replace(/\\/+$/, '');\n const normalizedPath = path.startsWith('/') ? path : `/${path}`;\n const url = new URL(`${base}${normalizedPath}`);\n\n Object.entries(query || {}).forEach(([key, value]) => {\n if (value === undefined || value === null || value === '') {\n return;\n }\n url.searchParams.set(key, String(value));\n });\n\n return url.toString();\n }\n\n private buildHeaders(\n headers?: unknown,\n hasJsonBody = false\n ): Record<string, string> {\n const merged = normalizeHeaders(headers);\n merged.Accept = 'application/json';\n merged['User-Agent'] = getUserAgent();\n\n if (hasJsonBody) {\n merged['Content-Type'] = 'application/json';\n }\n if (this.options.token) {\n merged.Authorization = `Bearer ${this.options.token}`;\n }\n if (this.options.refreshToken) {\n merged['X-Refresh-Token'] = this.options.refreshToken;\n }\n\n return merged;\n }\n}\n\nfunction normalizeHeaders(headers?: unknown): Record<string, string> {\n if (!headers) {\n return {};\n }\n if (typeof Headers !== 'undefined' && headers instanceof Headers) {\n return Object.fromEntries(headers.entries());\n }\n if (Array.isArray(headers)) {\n return Object.fromEntries(\n (headers as HeaderTupleList).map(([key, value]) => [String(key), String(value)])\n );\n }\n const normalized: Record<string, string> = {};\n Object.entries(headers as HeaderObjectInput).forEach(([key, value]) => {\n normalized[key] = typeof value === 'string' ? value : value.join(', ');\n });\n return normalized;\n}\n","import type { APIResponse } from './client';\nimport { DimensClient } from './client';\n\nexport interface LoginPayload {\n username: string;\n password: string;\n captchaId?: string;\n verifyCode?: string;\n}\n\nexport interface ApiKeyLoginPayload {\n apiKey: string;\n apiSecret: string;\n}\n\nexport interface LoginResult {\n token: string;\n refreshToken?: string;\n expire?: number;\n userInfo?: Record<string, unknown>;\n}\n\nexport interface RefreshTokenResult {\n token: string;\n refreshToken?: string;\n expire?: number;\n}\n\nexport class AuthSDK {\n constructor(private readonly client: DimensClient) {}\n\n login(payload: LoginPayload): Promise<APIResponse<LoginResult>> {\n return this.client.post<LoginResult>('/login', payload);\n }\n\n loginByApiKey(payload: ApiKeyLoginPayload): Promise<APIResponse<LoginResult>> {\n return this.client.post<LoginResult>('/open/user/login/apiKey', payload);\n }\n\n exchangeTokenByApiKey(\n payload: ApiKeyLoginPayload\n ): Promise<APIResponse<LoginResult>> {\n return this.loginByApiKey(payload);\n }\n\n refreshToken(): Promise<APIResponse<RefreshTokenResult>> {\n return this.client.get<RefreshTokenResult>('/refreshToken');\n }\n}\n","import type { APIResponse } from './client';\nimport { DimensClient } from './client';\n\nexport interface ColumnInfo {\n id: string;\n title?: string;\n label?: string;\n type?: string;\n [key: string]: unknown;\n}\n\nexport interface ColumnMutationPayload {\n title?: string;\n label?: string;\n type?: string;\n description?: string;\n [key: string]: unknown;\n}\n\nexport class ColumnSDK {\n constructor(private readonly client: DimensClient) {}\n\n list(\n teamId: string,\n projectId: string,\n sheetId: string\n ): Promise<APIResponse<ColumnInfo[]>> {\n return this.client.get<ColumnInfo[]>(\n `/app/mul/${teamId}/${projectId}/sheet/${sheetId}/column/list`\n );\n }\n\n create(\n teamId: string,\n projectId: string,\n sheetId: string,\n payload: ColumnMutationPayload\n ): Promise<APIResponse<ColumnInfo>> {\n return this.client.post<ColumnInfo>(\n `/app/mul/${teamId}/${projectId}/sheet/${sheetId}/column/create`,\n payload\n );\n }\n\n update(\n sheetId: string,\n fieldId: string,\n payload: ColumnMutationPayload\n ): Promise<APIResponse<ColumnInfo>> {\n return this.client.post<ColumnInfo>(\n `/app/mul/sheet/${sheetId}/column/${fieldId}/update`,\n payload\n );\n }\n\n delete(sheetId: string, fieldId: string): Promise<APIResponse<boolean>> {\n return this.client.post<boolean>(`/app/mul/sheet/${sheetId}/column/${fieldId}/delete`);\n }\n}\n","import type { APIResponse } from './client';\nimport { DimensClient } from './client';\n\nexport interface ProjectInfo {\n id: string;\n name: string;\n [key: string]: unknown;\n}\n\nexport interface ProjectPagePayload {\n page?: number;\n size?: number;\n keyword?: string;\n [key: string]: unknown;\n}\n\nexport interface ProjectPageResult {\n list: ProjectInfo[];\n pagination?: Record<string, unknown>;\n [key: string]: unknown;\n}\n\nexport interface ProjectMutationPayload {\n id?: string;\n name?: string;\n icon?: string;\n remark?: string;\n [key: string]: unknown;\n}\n\nexport class ProjectSDK {\n constructor(private readonly client: DimensClient) {}\n\n page(teamId: string, payload: ProjectPagePayload): Promise<APIResponse<ProjectPageResult>> {\n return this.client.post<ProjectPageResult>(`/app/org/${teamId}/project/page`, payload);\n }\n\n info(teamId: string, id: string): Promise<APIResponse<ProjectInfo>> {\n return this.client.get<ProjectInfo>(`/app/org/${teamId}/project/info`, { id });\n }\n\n create(\n teamId: string,\n payload: ProjectMutationPayload\n ): Promise<APIResponse<ProjectInfo>> {\n return this.client.post<ProjectInfo>(`/app/org/${teamId}/project/add`, payload);\n }\n\n update(\n teamId: string,\n payload: ProjectMutationPayload\n ): Promise<APIResponse<ProjectInfo>> {\n return this.client.post<ProjectInfo>(`/app/org/${teamId}/project/update`, payload);\n }\n\n trash(teamId: string, ids: string[]): Promise<APIResponse<boolean>> {\n return this.client.post<boolean>(`/app/org/${teamId}/project/trash`, { ids });\n }\n\n restore(teamId: string, ids: string[]): Promise<APIResponse<boolean>> {\n return this.client.post<boolean>(`/app/org/${teamId}/project/restore`, { ids });\n }\n}\n","import type { APIResponse } from './client';\nimport { DimensClient } from './client';\n\nexport interface RowInfo {\n id: string;\n [key: string]: unknown;\n}\n\nexport interface RowPagePayload {\n page?: number;\n size?: number;\n viewId?: string;\n filters?: unknown[];\n sorter?: unknown;\n [key: string]: unknown;\n}\n\nexport interface RowPageResult {\n list: RowInfo[];\n total?: number;\n [key: string]: unknown;\n}\n\nexport interface RowCreatePayload {\n data?: Record<string, unknown>;\n [key: string]: unknown;\n}\n\nexport interface RowCellPayload {\n rowId: string;\n fieldId: string;\n value: unknown;\n version?: number;\n [key: string]: unknown;\n}\n\nexport class RowSDK {\n constructor(private readonly client: DimensClient) {}\n\n page(\n teamId: string,\n projectId: string,\n sheetId: string,\n payload: RowPagePayload\n ): Promise<APIResponse<RowPageResult>> {\n return this.client.post<RowPageResult>(\n `/app/mul/${teamId}/${projectId}/sheet/${sheetId}/row/page`,\n payload\n );\n }\n\n info(\n teamId: string,\n projectId: string,\n sheetId: string,\n rowId: string\n ): Promise<APIResponse<RowInfo>> {\n return this.client.get<RowInfo>(\n `/app/mul/${teamId}/${projectId}/sheet/${sheetId}/row/${rowId}/info`\n );\n }\n\n create(sheetId: string, payload: RowCreatePayload): Promise<APIResponse<RowInfo>> {\n return this.client.post<RowInfo>(`/app/mul/sheet/${sheetId}/row/create`, payload);\n }\n\n update(\n sheetId: string,\n rowId: string,\n data: Record<string, unknown>,\n version: number\n ): Promise<APIResponse<RowInfo>> {\n return this.client.post<RowInfo>(`/app/mul/sheet/${sheetId}/row/${rowId}/update`, {\n data,\n version,\n });\n }\n\n delete(sheetId: string, rowId: string): Promise<APIResponse<boolean>> {\n return this.client.post<boolean>(`/app/mul/sheet/${sheetId}/row/${rowId}/delete`);\n }\n\n updateCell(sheetId: string, payload: RowCellPayload): Promise<APIResponse<boolean>> {\n return this.client.post<boolean>(`/app/mul/sheet/${sheetId}/row/cell`, payload);\n }\n}\n","import type { APIResponse } from './client';\nimport { DimensClient } from './client';\n\nexport interface SheetInfo {\n id: string;\n name?: string;\n [key: string]: unknown;\n}\n\nexport interface SheetMutationPayload {\n name?: string;\n icon?: string;\n folderId?: string;\n [key: string]: unknown;\n}\n\nexport class SheetSDK {\n constructor(private readonly client: DimensClient) {}\n\n list(projectId: string): Promise<APIResponse<SheetInfo[]>> {\n return this.client.get<SheetInfo[]>(`/app/mul/project/${projectId}/sheet/list`);\n }\n\n tree(projectId: string): Promise<APIResponse<unknown[]>> {\n return this.client.get<unknown[]>(`/app/mul/project/${projectId}/sheet/tree`);\n }\n\n create(projectId: string, payload: SheetMutationPayload): Promise<APIResponse<SheetInfo>> {\n return this.client.post<SheetInfo>(`/app/mul/project/${projectId}/sheet/create`, payload);\n }\n\n info(teamId: string, projectId: string, sheetId: string): Promise<APIResponse<SheetInfo>> {\n return this.client.get<SheetInfo>(\n `/app/mul/${teamId}/${projectId}/sheet/${sheetId}/info`\n );\n }\n\n update(\n teamId: string,\n projectId: string,\n sheetId: string,\n payload: SheetMutationPayload\n ): Promise<APIResponse<SheetInfo>> {\n return this.client.post<SheetInfo>(\n `/app/mul/${teamId}/${projectId}/sheet/${sheetId}/update`,\n payload\n );\n }\n\n delete(teamId: string, projectId: string, sheetId: string): Promise<APIResponse<boolean>> {\n return this.client.post<boolean>(\n `/app/mul/${teamId}/${projectId}/sheet/${sheetId}/delete`\n );\n }\n\n structure(sheetId: string): Promise<APIResponse<Record<string, unknown>>> {\n return this.client.get<Record<string, unknown>>(`/app/mul/sheet/${sheetId}/structure`);\n }\n}\n"],"mappings":"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"} |
| # 系统搭建命令映射 | ||
| ## 1. 使用目的 | ||
| 这份文档把“系统级搭建步骤”直接映射到可执行命令或接口,避免总控 Skill 只停留在路由建议,导致 AI 还要自己继续摸索具体参数。 | ||
| ## 2. 执行前检查 | ||
| ### 2.1 先完成认证 | ||
| 推荐优先使用: | ||
| ```bash | ||
| dimens-cli auth api-key-login \ | ||
| --base-url https://dimens.bintelai.com \ | ||
| --api-key ak_xxx \ | ||
| --api-secret sk_xxx | ||
| ``` | ||
| 如果还不清楚认证边界,先看: | ||
| - `../dimens-key-auth/references/login-flow.md` | ||
| - `../dimens-key-auth/references/examples.md` | ||
| ### 2.2 再确认上下文 | ||
| ```bash | ||
| dimens-cli auth use-team TEAM_ID | ||
| dimens-cli project list --team-id TEAM_ID | ||
| ``` | ||
| ## 3. 系统搭建步骤 → 命令 | ||
| | 系统搭建步骤 | 优先命令 | 说明 | | ||
| | --- | --- | --- | | ||
| | 确认团队与项目上下文 | `dimens-cli project list --team-id TEAM_ID` | 系统建设前先确认项目归属 | | ||
| | 创建项目 | `dimens-cli project create --team-id TEAM_ID --name 项目名` | 所有表都挂在项目下 | | ||
| | 查看项目详情 | `dimens-cli project info --team-id TEAM_ID --project-id PROJECT_ID` | 校验上下文是否正确 | | ||
| | 创建工作表 | `dimens-cli sheet create --team-id TEAM_ID --project-id PROJECT_ID --name 表名` | 新系统一般先建核心表 | | ||
| | 查看表详情 | `dimens-cli sheet info --team-id TEAM_ID --project-id PROJECT_ID --sheet-id SHEET_ID` | 校验表结构 | | ||
| | 查看字段列表 | `dimens-cli column list --team-id TEAM_ID --project-id PROJECT_ID --sheet-id SHEET_ID` | 写入行数据前必须先取字段 | | ||
| | 创建字段 | `dimens-cli column create --team-id TEAM_ID --project-id PROJECT_ID --sheet-id SHEET_ID --label 字段名 --type text` | 推荐统一使用 `--label` | | ||
| | 创建行 | `dimens-cli row create --sheet-id SHEET_ID --values '{\"fld_xxx\":\"值\"}'` | CLI 会映射到服务端 `data` | | ||
| | 更新行 | `dimens-cli row update --sheet-id SHEET_ID --row-id ROW_ID --version 1 --values '{\"fld_xxx\":\"新值\"}'` | 更新前要拿到版本号 | | ||
| | 更新单元格 | `dimens-cli row set-cell --sheet-id SHEET_ID --row-id ROW_ID --field-id FIELD_ID --value 新值 --version 1` | 推荐用 `fieldId`,不要用中文字段名 | | ||
| | 查询行数据 | `dimens-cli row page --team-id TEAM_ID --project-id PROJECT_ID --sheet-id SHEET_ID --page 1 --size 20` | 验证表是否可用 | | ||
| ## 4. CRM 最小可执行链路 | ||
| ### 4.1 创建项目 | ||
| ```bash | ||
| dimens-cli project create --team-id TEAM_ID --name 客户管理系统 | ||
| ``` | ||
| ### 4.2 创建客户表 | ||
| ```bash | ||
| dimens-cli sheet create --team-id TEAM_ID --project-id PROJECT_ID --name 客户表 | ||
| ``` | ||
| ### 4.3 创建字段 | ||
| ```bash | ||
| dimens-cli column create \ | ||
| --team-id TEAM_ID \ | ||
| --project-id PROJECT_ID \ | ||
| --sheet-id SHEET_ID \ | ||
| --label 客户名称 \ | ||
| --type text | ||
| ``` | ||
| ```bash | ||
| dimens-cli column create \ | ||
| --team-id TEAM_ID \ | ||
| --project-id PROJECT_ID \ | ||
| --sheet-id SHEET_ID \ | ||
| --label 客户等级 \ | ||
| --type select | ||
| ``` | ||
| 补充: | ||
| - `select`、`multiSelect` 等字段通常还需要额外 `config` | ||
| - 如需确认字段结构,优先回看 `../dimens-table/references/field-design-patterns.md` | ||
| ### 4.4 先查字段,再写行 | ||
| ```bash | ||
| dimens-cli column list \ | ||
| --team-id TEAM_ID \ | ||
| --project-id PROJECT_ID \ | ||
| --sheet-id SHEET_ID | ||
| ``` | ||
| ### 4.5 用 fieldId 写入行 | ||
| ```bash | ||
| dimens-cli row create \ | ||
| --sheet-id SHEET_ID \ | ||
| --values '{"fld_customerName":"华东智造","fld_customerLevel":"A"}' | ||
| ``` | ||
| ## 5. 必须显式提醒的坑 | ||
| | 坑点 | 正确做法 | | ||
| | --- | --- | | ||
| | 没登录就直接跑表格命令 | 先执行 `auth api-key-login` 或其他认证链路 | | ||
| | 创建字段还用 `--title` 当规范写法 | 现在兼容,但推荐统一改成 `--label` | | ||
| | 行写入直接用中文字段名 | 先查字段列表,拿 `fieldId` 再写 | | ||
| | `row set-cell` 继续用 `columnId` 理解服务端 | 服务端真实字段是 `fieldId`,`columnId` 只是兼容参数 | | ||
| | 忽略 `version` | 行更新和单元格更新都建议显式带 `version` | |
+6
-3
@@ -61,2 +61,3 @@ //#region src/sdk/client.d.ts | ||
| title?: string; | ||
| label?: string; | ||
| type?: string; | ||
@@ -67,2 +68,3 @@ [key: string]: unknown; | ||
| title?: string; | ||
| label?: string; | ||
| type?: string; | ||
@@ -170,3 +172,3 @@ description?: string; | ||
| interface RowCreatePayload { | ||
| values?: Record<string, unknown>; | ||
| data?: Record<string, unknown>; | ||
| [key: string]: unknown; | ||
@@ -176,4 +178,5 @@ } | ||
| rowId: string; | ||
| columnId: string; | ||
| fieldId: string; | ||
| value: unknown; | ||
| version?: number; | ||
| [key: string]: unknown; | ||
@@ -187,3 +190,3 @@ } | ||
| create(sheetId: string, payload: RowCreatePayload): Promise<APIResponse<RowInfo>>; | ||
| update(sheetId: string, rowId: string, values: Record<string, unknown>, version: number): Promise<APIResponse<RowInfo>>; | ||
| update(sheetId: string, rowId: string, data: Record<string, unknown>, version: number): Promise<APIResponse<RowInfo>>; | ||
| delete(sheetId: string, rowId: string): Promise<APIResponse<boolean>>; | ||
@@ -190,0 +193,0 @@ updateCell(sheetId: string, payload: RowCellPayload): Promise<APIResponse<boolean>>; |
@@ -1,1 +0,1 @@ | ||
| {"version":3,"file":"index.d.mts","names":[],"sources":["../src/sdk/client.ts","../src/sdk/auth.ts","../src/sdk/column.ts","../src/sdk/flow-chat.ts","../src/sdk/project.ts","../src/sdk/row.ts","../src/sdk/sheet.ts","../src/sdk/index.ts","../src/types.ts","../src/core/logger.ts","../src/core/config.ts","../src/core/version.ts","../src/tools/registry.ts","../src/tools/index.ts","../src/commands/registry.ts","../src/commands/index.ts","../src/cli.ts","../src/skills/index.ts","../index.ts"],"mappings":"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"} | ||
| {"version":3,"file":"index.d.mts","names":[],"sources":["../src/sdk/client.ts","../src/sdk/auth.ts","../src/sdk/column.ts","../src/sdk/flow-chat.ts","../src/sdk/project.ts","../src/sdk/row.ts","../src/sdk/sheet.ts","../src/sdk/index.ts","../src/types.ts","../src/core/logger.ts","../src/core/config.ts","../src/core/version.ts","../src/tools/registry.ts","../src/tools/index.ts","../src/commands/registry.ts","../src/commands/index.ts","../src/cli.ts","../src/skills/index.ts","../index.ts"],"mappings":"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"} |
+5
-5
| import { n as logger, t as createLogger } from "./logger-CEOtAYhF.mjs"; | ||
| import { _ as config, a as getRelatedSkillObjectsForExecutionContext, c as getAllSkills, d as clearCommands, f as getAllCommands, g as registerCommand, h as getGroupCommand, i as clearExecutionContext, l as getSkill, m as getCommandGroup, n as registerCommands, o as setExecutionContext, p as getCommand, r as parseFlags, s as SKILLS, u as getSkillsRootPath } from "./commands-CRE0o0GP.mjs"; | ||
| import { a as AuthSDK, c as getUserAgent, i as ColumnSDK, l as getVersion, n as RowSDK, o as DimensClient, r as ProjectSDK, s as FlowChatSDK, t as SheetSDK, u as version } from "./sheet-DafechaB.mjs"; | ||
| import { _ as config, a as getRelatedSkillObjectsForExecutionContext, c as getAllSkills, d as clearCommands, f as getAllCommands, g as registerCommand, h as getGroupCommand, i as clearExecutionContext, l as getSkill, m as getCommandGroup, n as registerCommands, o as setExecutionContext, p as getCommand, r as parseFlags, s as SKILLS, u as getSkillsRootPath } from "./commands-DhXU3rGj.mjs"; | ||
| import { a as AuthSDK, c as getUserAgent, i as ColumnSDK, l as getVersion, n as RowSDK, o as DimensClient, r as ProjectSDK, s as FlowChatSDK, t as SheetSDK, u as version } from "./sheet-jiBqJC3e.mjs"; | ||
| import { a as registerTool, i as getTool, r as getAllTools, t as registerAllTools } from "./tools-C66Gl8k6.mjs"; | ||
| import { n as createSDK, t as DimensSDK } from "./sdk-CTc2yzdu.mjs"; | ||
| import { n as createSDK, t as DimensSDK } from "./sdk-DAD4AM5p.mjs"; | ||
| import { readFileSync } from "node:fs"; | ||
@@ -106,3 +106,3 @@ import { relative } from "node:path"; | ||
| const { registerAllTools } = await import("./tools-C66Gl8k6.mjs").then((n) => n.n); | ||
| const { registerCommands } = await import("./commands-CRE0o0GP.mjs").then((n) => n.t); | ||
| const { registerCommands } = await import("./commands-DhXU3rGj.mjs").then((n) => n.t); | ||
| return { | ||
@@ -119,3 +119,3 @@ name: "@bintel/dimens-cli", | ||
| async function createDimensSDK(config) { | ||
| const { DimensSDK } = await import("./sdk-CTc2yzdu.mjs").then((n) => n.r); | ||
| const { DimensSDK } = await import("./sdk-DAD4AM5p.mjs").then((n) => n.r); | ||
| if (!config) throw new Error("createDimensSDK 需要传入 baseUrl"); | ||
@@ -122,0 +122,0 @@ return new DimensSDK(config); |
+1
-1
| { | ||
| "name": "@bintel/dimens-cli", | ||
| "version": "1.0.1", | ||
| "version": "1.0.2", | ||
| "description": "Dimens CLI 与 Node.js SDK,提供多维项目的认证、项目、表格、行数据与 AI chat-completions 调用能力", | ||
@@ -5,0 +5,0 @@ "type": "module", |
+2
-0
@@ -54,2 +54,4 @@ # Dimens CLI | ||
| 如果你本地执行 `dimens-cli` 提示“command not found”,说明当前环境还没有这个命令。先安装 `@bintel/dimens-cli`,安装完成后再继续看 `skills/` 文档、CLI 案例和 Skill 路由说明。 | ||
| 如果你是在当前仓库里开发 `dimens-cli`,再看下面的“本地开发使用”。 | ||
@@ -56,0 +58,0 @@ |
| # dimens-key-auth 接口案例 | ||
| 本文档只写当前仓库里已经能对照到的真实接口、CLI 命令和返回结构,重点覆盖: | ||
| 本文档只写维表智联当前已经可用的真实接口、CLI 命令和返回结构,重点覆盖: | ||
@@ -25,3 +25,3 @@ 1. `apiKey + apiSecret` 换 token | ||
| | 路径 | `/open/user/login/apiKey` | | ||
| | 控制器 | `server/src/modules/user/controller/open/login.ts` | | ||
| | 入口角色 | 开放登录接口 | | ||
| | 鉴权 | 不需要 Bearer token | | ||
@@ -58,3 +58,3 @@ | 请求体 | `apiKey`、`apiSecret` | | ||
| | `data.expire` | `number` | access token 过期秒数 | | ||
| | `data.token` | `string` | 当前系统用户 JWT | | ||
| | `data.token` | `string` | 维表智联用户 JWT | | ||
| | `data.refreshExpire` | `number` | refresh token 过期秒数 | | ||
@@ -152,3 +152,3 @@ | `data.refreshToken` | `string` | 刷新 token | | ||
| 这些接口当前主要由 `web` 和 `server` 支持,CLI 还没有完全封装成独立命令,但 Skill 里不能遗漏。 | ||
| 这些接口当前主要由维表智联平台提供,CLI 还没有完全封装成独立命令,但 Skill 里不能遗漏。 | ||
@@ -162,3 +162,3 @@ ### 2.1 创建 API Key | ||
| | 鉴权 | `Authorization: Bearer {token}` | | ||
| | 控制器 | `.trae/使用方案/key 使用方案.md` 与 `server/src/modules/base/controller/app/api_key.ts` | | ||
| | 入口角色 | API Key 管理入口 | | ||
@@ -165,0 +165,0 @@ 请求体: |
| # dimens-key-auth 登录链路说明 | ||
| 适用产品: | ||
| - 产品名称:`维表智联` | ||
| - 开发方:`方块智联工作室` | ||
| - 官网:[https://dimens.bintelai.com/](https://dimens.bintelai.com/) | ||
| 本文档把 API Key 登录链路拆成“接口请求”、“CLI 行为”、“后续业务访问”三段,便于 Skill 在解释问题时不混淆。 | ||
@@ -22,4 +28,4 @@ | ||
| | 路径 | `/open/user/login/apiKey` | | ||
| | 控制器 | `server/src/modules/user/controller/open/login.ts` | | ||
| | 服务 | `server/src/modules/user/service/login.ts` | | ||
| | 入口角色 | API Key 登录入口 | | ||
| | 能力归类 | 认证与令牌签发 | | ||
@@ -152,3 +158,3 @@ ### 1.2 请求体 | ||
| ## 4. 当前仓库里的真实闭环案例 | ||
| ## 4. 当前可复用的真实闭环案例 | ||
@@ -155,0 +161,0 @@ 本次已实测成功的真实链路: |
| --- | ||
| name: dimens-key-auth | ||
| description: | | ||
| 多维项目中的 API Key / API Secret 鉴权技能,覆盖 Key 创建、启停、删除、重置 Secret、登录换 token 与调用边界说明。 | ||
| 维表智联中的 API Key / API Secret 鉴权技能,覆盖 Key 创建、启停、删除、重置 Secret、登录换 token 与调用边界说明。 | ||
@@ -16,2 +16,8 @@ **当以下情况时使用此 Skill**: | ||
| 适用产品: | ||
| - 产品名称:`维表智联` | ||
| - 开发方:`方块智联工作室` | ||
| - 官网:[https://dimens.bintelai.com/](https://dimens.bintelai.com/) | ||
| ## 执行前必读 | ||
@@ -78,9 +84,10 @@ | ||
| | 文档 | 作用 | 什么时候必须看 | | ||
| | Skill / references | 作用 | 什么时候必须看 | | ||
| | --- | --- | --- | | ||
| | `AGENTS.md` | 仓库总规则、模块定位、文档优先级 | 每次处理本仓库都要先看 | | ||
| | `.trae/使用方案/key 使用方案.md` | API Key / Secret 换 token 的真实能力边界 | 处理 Key 登录时必须看 | | ||
| | `dimens-cli/文档/cli 命令使用指南.md` | 当前 CLI 中 `auth api-key-login` 的真实命令入口 | 给 CLI 示例时必须看 | | ||
| | `dimens-cli/文档/业务控制说明.md` | CLI/SDK 与后端能力映射 | 设计工具或命令映射时必须看 | | ||
| | `.trae/已开发文档/团队项目管理设计.md` | 团队和项目权限的上游隔离模型 | 分析换 token 后访问受限时建议看 | | ||
| | `dimens-team` | 团队与项目权限的上游隔离模型 | 分析换 token 后访问受限时建议看 | | ||
| | `dimens-permission` | 为什么换 token 成功后仍然可能没有资源权限 | 解释访问受限时建议看 | | ||
| | `references/login-flow.md` | Key 登录链路与 token 复用方式 | 处理 Key 登录时必须看 | | ||
| | `references/integration-boundaries.md` | 第三方调用边界 | 解释对接方式时必须看 | | ||
| | `references/capability-status.md` | 当前 Key 能力范围 | 判断当前支持范围时建议看 | | ||
| | `references/examples.md` | Key 登录和管理案例 | 需要直接举例时看 | | ||
@@ -87,0 +94,0 @@ ## 使用场景示例 |
@@ -9,3 +9,3 @@ # dimens-permission 接口案例 | ||
| 4. Yjs 协同连接与权限快照入口 | ||
| 5. 当前 CLI 未直接封装,但 Skill 必须解释的 server 真实接口 | ||
| 5. 当前 CLI 未直接封装,但 Skill 必须解释的平台真实接口 | ||
@@ -29,6 +29,4 @@ 更细的规则说明请分别查看: | ||
| 项目准入的关键中间件: | ||
| 项目准入依赖项目访问校验链路。 | ||
| - `server/src/modules/org/middleware/project_authority.ts` | ||
| 准入判断要点: | ||
@@ -67,3 +65,3 @@ | ||
| | 前缀 | `/app/mul/project/:projectId/permission` | | ||
| | 控制器 | `server/src/modules/mul/controller/app/permission.ts` | | ||
| | 入口角色 | 项目权限管理入口 | | ||
@@ -174,3 +172,3 @@ 这些接口当前主要服务于项目内权限管理界面和权限诊断,CLI 还没有直接封装,但 Skill 不能遗漏。 | ||
| | 前缀 | `/app/mul/project/:projectId/row_policy` | | ||
| | 控制器 | `server/src/modules/mul/controller/app/row_policy.ts` | | ||
| | 入口角色 | 行级策略入口 | | ||
@@ -289,3 +287,3 @@ ### 3.2 查询策略列表 | ||
| | 协议入口 | `/mul/yjs/*` | | ||
| | 控制器 | `server/src/modules/mul/controller/app/yjsCollaboration.ts` | | ||
| | 入口角色 | 协同连接入口 | | ||
@@ -292,0 +290,0 @@ 连接查询参数重点: |
| --- | ||
| name: dimens-permission | ||
| description: | | ||
| 多维项目中的权限技能,覆盖团队准入、表级权限、列级权限、行级权限、公开访问者、协同权限快照与广播过滤。 | ||
| 维表智联中的权限技能,覆盖团队准入、表级权限、列级权限、行级权限、公开访问者、协同权限快照与广播过滤。 | ||
@@ -16,2 +16,8 @@ **当以下情况时使用此 Skill**: | ||
| 适用产品: | ||
| - 产品名称:`维表智联` | ||
| - 开发方:`方块智联工作室` | ||
| - 官网:[https://dimens.bintelai.com/](https://dimens.bintelai.com/) | ||
| ## 执行前必读 | ||
@@ -72,11 +78,10 @@ | ||
| | 文档 | 作用 | 什么时候必须看 | | ||
| | Skill / references | 作用 | 什么时候必须看 | | ||
| | --- | --- | --- | | ||
| | `AGENTS.md` | 仓库总规则、模块定位、文档优先级 | 每次处理本仓库都要先看 | | ||
| | `.trae/已开发文档/权限机制架构设计图.md` | 权限五层结构、公开访问者、权限事实源 | 处理权限问题时必须看 | | ||
| | `.trae/已开发文档/权限流程图.md` | 行分页读取 + Yjs 权限链路 | 处理行级和协同问题时必须看 | | ||
| | `.trae/已开发文档/权限+协同测试用例清单.md` | 高风险权限协同回归点 | 设计测试与排查时建议看 | | ||
| | `.trae/已开发文档/yjs-socket 协作指南.md` | 协同写入、广播过滤、前端行守卫 | 协同问题时必须看 | | ||
| | `.trae/已开发文档/redis架构方案.md` | 权限缓存与协同缓存隔离规则 | 涉及缓存时必须看 | | ||
| | `dimens-cli/文档/业务控制说明.md` | CLI/SDK 与权限相关接口映射 | 写命令型 Skill 时建议看 | | ||
| | `dimens-team` | 团队 / 项目准入与角色边界 | 处理能进不能看时必须先看 | | ||
| | `dimens-table` | 表、字段、行数据为什么被继续收窄 | 处理表格权限时建议看 | | ||
| | `references/matrix.md` | 五层权限结构与判断矩阵 | 处理权限问题时必须看 | | ||
| | `references/scenario-routing.md` | 场景排查路径 | 设计排查步骤时必须看 | | ||
| | `references/capability-status.md` | 当前权限相关能力范围 | 判断是否已 CLI 封装时建议看 | | ||
| | `references/examples.md` | 权限场景案例 | 需要直接举例时看 | | ||
@@ -83,0 +88,0 @@ ## 使用场景示例 |
| # dimens-report 接口案例 | ||
| 本文档聚焦当前 `server` 里已经落地的报表模块接口,按接口维度整理: | ||
| 本文档聚焦维表智联当前已经落地的报表模块接口,按接口维度整理: | ||
@@ -27,3 +27,3 @@ 1. 报表列表 / 详情 / 增删改 | ||
| | 前缀 | `/app/report/:projectId` | | ||
| | 控制器 | `server/src/modules/report/controller/app/info.ts` | | ||
| | 入口角色 | 报表主资源入口 | | ||
@@ -126,3 +126,3 @@ ### 1.2 查询报表列表 | ||
| | 前缀 | `/app/report/widget/:projectId` | | ||
| | 控制器 | `server/src/modules/report/controller/app/widget.ts` | | ||
| | 入口角色 | 图表组件入口 | | ||
@@ -188,3 +188,3 @@ ### 2.2 新增组件 | ||
| | 前缀 | `/app/report/query/:projectId` | | ||
| | 控制器 | `server/src/modules/report/controller/app/query.ts` | | ||
| | 入口角色 | 报表查询入口 | | ||
@@ -268,3 +268,3 @@ ### 3.2 执行整个报表查询 | ||
| | 前缀 | `/app/report/template` | | ||
| | 控制器 | `server/src/modules/report/controller/app/template.ts` | | ||
| | 入口角色 | 报表模板入口 | | ||
@@ -341,3 +341,3 @@ ## 6. 这份文档的职责边界 | ||
| | 前缀 | `/app/report/version/:projectId` | | ||
| | 控制器 | `server/src/modules/report/controller/app/version.ts` | | ||
| | 入口角色 | 报表版本入口 | | ||
@@ -344,0 +344,0 @@ ### 5.2 版本列表 |
| --- | ||
| name: dimens-report | ||
| description: | | ||
| 报表技能,覆盖报表、图表组件、参数联动、数据源配置、查询链路和项目级权限边界。 | ||
| 维表智联中的报表技能,覆盖报表、图表组件、参数联动、数据源配置、查询链路和项目级权限边界。 | ||
@@ -16,2 +16,8 @@ **当以下情况时使用此 Skill**: | ||
| 适用产品: | ||
| - 产品名称:`维表智联` | ||
| - 开发方:`方块智联工作室` | ||
| - 官网:[https://dimens.bintelai.com/](https://dimens.bintelai.com/) | ||
| ## 执行前必读 | ||
@@ -63,9 +69,10 @@ | ||
| | 文档 | 作用 | 什么时候必须看 | | ||
| | Skill / references | 作用 | 什么时候必须看 | | ||
| | --- | --- | --- | | ||
| | `AGENTS.md` | 仓库总规则、模块定位、文档优先级 | 每次处理本仓库都要先看 | | ||
| | `.trae/已开发文档/报表系统架构设计图.md` | 报表的数据源、组件、参数、权限与展示链路 | 处理报表时必须看 | | ||
| | `.trae/已开发文档/团队项目管理设计.md` | 项目级资源边界 | 解释项目权限时建议看 | | ||
| | `.trae/已开发文档/权限机制架构设计图.md` | 项目与资源权限层级 | 排查访问问题时建议看 | | ||
| | `dimens-cli/文档/业务控制说明.md` | CLI/SDK 与业务接口映射 | 写命令型 Skill 时必须看 | | ||
| | `dimens-team` | 项目级资源边界与上下文 | 处理报表时必须先看 | | ||
| | `dimens-table` | 多维表格数据源与字段映射 | 报表基于表格数据源时必须看 | | ||
| | `dimens-permission` | 项目权限、数据访问范围与可见性 | 解释访问问题时建议看 | | ||
| | `references/usage.md` | 报表使用分层说明 | 处理报表时必须看 | | ||
| | `references/capability-status.md` | 当前报表能力范围 | 判断是否已封装时建议看 | | ||
| | `references/examples.md` | 报表 / 图表 / 参数接口案例 | 需要直接举例时看 | | ||
@@ -72,0 +79,0 @@ ## 使用场景示例 |
@@ -133,2 +133,3 @@ # dimens-system-orchestrator Skill 路由规则 | ||
| - `../../references/cli-api-catalog.md` | ||
| - `command-mapping.md` | ||
@@ -135,0 +136,0 @@ ## 9. 输出时必须显式标记的三种状态 |
| --- | ||
| name: dimens-system-orchestrator | ||
| description: | | ||
| 多维项目中的系统级总控编排技能,用于接住“生成一个 XX 系统 / 平台 / 管理系统 / 业务系统”这类系统建设需求,先做系统拆解,再路由到合适的子 Skill。 | ||
| 维表智联中的系统级总控编排技能,用于接住“生成一个 XX 系统 / 平台 / 管理系统 / 业务系统”这类系统建设需求,先做系统拆解,再路由到合适的子 Skill。 | ||
@@ -16,4 +16,12 @@ **当以下情况时使用此 Skill**: | ||
| 适用产品: | ||
| - 产品名称:`维表智联` | ||
| - 开发方:`方块智联工作室` | ||
| - 官网:[https://dimens.bintelai.com/](https://dimens.bintelai.com/) | ||
| ## 执行前必读 | ||
| - ✅ 如果本地还没有 `dimens-cli` 命令,先安装 `@bintel/dimens-cli`,否则后续命令和 Skill 路由案例无法直接执行 | ||
| - ✅ 在路由到任何业务 Skill 前,先确认认证是否完成;未认证时优先进入 `dimens-key-auth` | ||
| - ✅ 这是系统级总控 Skill,不直接替代 `dimens-team`、`dimens-table`、`dimens-permission` 等业务 Skill | ||
@@ -142,12 +150,13 @@ - ✅ 默认节奏是“先方案,后执行”,不能在系统边界没拆清时直接开始落地 | ||
| | 文档 | 作用 | 什么时候必须看 | | ||
| | Skill / references | 作用 | 什么时候必须看 | | ||
| | --- | --- | --- | | ||
| | `AGENTS.md` | 仓库总规则、模块定位、文档优先级 | 每次处理本仓库都要先看 | | ||
| | `dimens-cli/skills/README.md` | 当前 Skill 体系总览 | 做系统级路由时必须看 | | ||
| | `dimens-cli/文档/技能设计.md` | Skill 分类、写法与 references 规范 | 维护系统级 Skill 时必须看 | | ||
| | `.trae/已开发文档/团队项目管理设计.md` | 团队和项目隔离模型 | 系统拆解时必须看 | | ||
| | `.trae/已开发文档/权限机制架构设计图.md` | 权限五层结构 | 涉及角色和数据范围时必须看 | | ||
| | `.trae/已开发文档/工作流架构设计.md` | 工作流前后端架构 | 涉及流程时必须看 | | ||
| | `.trae/已开发文档/报表系统架构设计图.md` | 报表链路与数据源 | 涉及看板时必须看 | | ||
| | `dimens-team` | 团队、项目、上下文和隔离模型 | 系统拆解时必须看 | | ||
| | `dimens-table` | 表、字段、关联、示例数据和查询案例 | 涉及建模时必须看 | | ||
| | `dimens-permission` | 准入、表列行权限、公开访问和协同边界 | 涉及权限时必须看 | | ||
| | `dimens-workflow` | 工作流、默认模型、项目挂载和运行调用 | 涉及流程时必须看 | | ||
| | `dimens-report` | 图表、看板、参数联动与数据源查询 | 涉及报表时必须看 | | ||
| | `dimens-key-auth` | API Key、token 复用和第三方接入 | 涉及对接时必须看 | | ||
| | `dimens-cli/skills/references/cli-api-catalog.md` | 当前 Skill 体系已覆盖接口总目录 | 做系统级路由时强烈建议看 | | ||
| | `references/command-mapping.md` | 系统建设步骤到 CLI / API 的直接映射 | 用户要求“直接给命令”时必须看 | | ||
@@ -191,2 +200,3 @@ ## 使用场景示例 | ||
| - `references/skill-routing.md` | ||
| - `references/command-mapping.md` | ||
| - `references/examples.md` |
@@ -148,3 +148,3 @@ # dimens-table 建模落地链路 | ||
| --sheet-id sh_customer \ | ||
| --title 客户名称 \ | ||
| --label 客户名称 \ | ||
| --type text | ||
@@ -158,2 +158,3 @@ ``` | ||
| - 最后建 relation 字段 | ||
| - 当前 CLI 已兼容旧参数 `--title`,但推荐统一改用 `--label`,与服务端字段名保持一致 | ||
@@ -210,3 +211,3 @@ --- | ||
| --sheet-id sh_customer \ | ||
| --values '{"客户名称":"华东智造","客户等级":"A","客户状态":"跟进中"}' | ||
| --values '{"fld_customerName":"华东智造","fld_customerLevel":"A","fld_customerStatus":"跟进中"}' | ||
| ``` | ||
@@ -216,4 +217,5 @@ | ||
| - 当前 CLI 写入链路和 server 真实请求体仍有 `部分对齐` 风险。 | ||
| - 因此文档里要明确这是“可用命令入口”,但不要把它包装成完全无差异的稳定契约。 | ||
| - 行创建前要先通过 `column list` 查询字段列表,拿到真实 `fieldId` | ||
| - `--values` 只是 CLI 参数名,CLI 内部会映射为服务端需要的 `data` | ||
| - 不要直接把中文字段名当请求体 key,服务端真实写入以 `fieldId` 为准 | ||
@@ -220,0 +222,0 @@ --- |
@@ -27,3 +27,3 @@ # dimens-table 接口案例 | ||
| | 路径 | `/app/mul/project/:projectId/sheet/list` | | ||
| | 控制器 | `server/src/modules/mul/controller/app/project.ts` | | ||
| | 入口角色 | 项目资源列表入口 | | ||
@@ -74,3 +74,3 @@ 路径参数: | ||
| | 路径 | `/app/mul/project/:projectId/sheet/tree` | | ||
| | 控制器 | `server/src/modules/mul/controller/app/project.ts` | | ||
| | 入口角色 | 项目资源树入口 | | ||
@@ -106,3 +106,3 @@ ### 2.2 CLI 命令 | ||
| | 路径 | `/app/mul/:teamId/:projectId/sheet/:sheetId/info` | | ||
| | 控制器 | `server/src/modules/mul/controller/app/sheet.ts` | | ||
| | 入口角色 | 表详情入口 | | ||
@@ -155,3 +155,3 @@ 路径参数: | ||
| | 路径 | `/app/mul/:teamId/:projectId/sheet/:sheetId/column/list` | | ||
| | 控制器 | `server/src/modules/mul/controller/app/column.ts` | | ||
| | 入口角色 | 字段列表入口 | | ||
@@ -229,3 +229,3 @@ 路径参数: | ||
| | 路径 | `/app/mul/:teamId/:projectId/sheet/:sheetId/row/page` | | ||
| | 控制器 | `server/src/modules/mul/controller/app/row.ts` | | ||
| | 入口角色 | 行分页入口 | | ||
@@ -294,5 +294,5 @@ 请求体: | ||
| ### 5.5 前端真实使用口径 | ||
| ### 5.5 平台真实使用口径 | ||
| 前端当前真实读取链路不是只传分页参数,而是会组合: | ||
| 维表智联在行分页读取时,不是只传分页参数,而是会组合: | ||
@@ -311,11 +311,4 @@ ```ts | ||
| 可对照位置: | ||
| Skill 解释筛选、搜索、排序时应按这个请求结构说明。详细查询案例已经拆到 `row-filters.md`,这里不再重复展开。 | ||
| - `web/src/store/sheetStore.ts` | ||
| - `web/src/api/mul/row.ts` | ||
| - `web/src/components/worksheet/hooks/useWorksheetLogic.ts` | ||
| - `web/src/components/mul-sheet/components/SmartSpreadsheet/SmartSpreadsheet.tsx` | ||
| 详细查询案例已经拆到 `row-filters.md`,这里不再重复展开。 | ||
| ### 5.4 真实分页案例:relation 目标表 `工作表 2` | ||
@@ -361,3 +354,3 @@ | ||
| | 路径 | `/app/mul/:teamId/:projectId/sheet/:sheetId/row/:rowId/info` | | ||
| | 控制器 | `server/src/modules/mul/controller/app/row.ts` | | ||
| | 入口角色 | 行详情入口 | | ||
@@ -418,11 +411,17 @@ ### 6.2 CLI 命令 | ||
| ## 7. 当前 CLI 与 server 的差异提醒 | ||
| ## 7. 当前 CLI 与平台接口的对齐说明 | ||
| ### 7.1 结论 | ||
| Skill 在解释写操作时,必须说明下列差异,不能假装已经完全对齐: | ||
| 当前 `row create`、`row update`、`row set-cell` 的 CLI 请求体已按 server 真实契约对齐。 | ||
| 仍需提醒的点: | ||
| - `row create` / `row update` 命令行参数仍然叫 `--values`,但 CLI 内部会映射为服务端需要的 `data` | ||
| - `row set-cell` 推荐使用 `--field-id`,旧参数 `--column-id` 仅保留兼容 | ||
| - 行写入时,字段 key 应使用 `fieldId`,不要直接使用中文字段名 | ||
| ### 7.2 行创建 | ||
| server 当前接口: | ||
| 平台当前接口: | ||
@@ -437,3 +436,3 @@ | 方法 | 路径 | 请求体 | | ||
| | --- | --- | | ||
| | `dimens-cli row create --sheet-id ... --values '{...}'` | `{ "values": { ... } }` | | ||
| | `dimens-cli row create --sheet-id ... --values '{...}'` | `{ "data": { ... } }` | | ||
@@ -443,3 +442,3 @@ 也就是说: | ||
| - `server` 当前真实入参是 `data` | ||
| - CLI 当前还在发 `values` | ||
| - CLI 命令参数仍叫 `values`,但实际已映射为 `data` | ||
@@ -458,3 +457,3 @@ ### 7.3 行更新 | ||
| | --- | --- | | ||
| | `dimens-cli row update ... --values '{...}' --version 1` | `{ "values": { ... }, "version": 1 }` | | ||
| | `dimens-cli row update ... --values '{...}' --version 1` | `{ "data": { ... }, "version": 1 }` | | ||
@@ -473,3 +472,3 @@ ### 7.4 单元格更新 | ||
| | --- | --- | | ||
| | `dimens-cli row set-cell ... --column-id ... --value ...` | `{ "rowId": "...", "columnId": "...", "value": ... }` | | ||
| | `dimens-cli row set-cell ... --field-id ... --value ... --version 1` | `{ "rowId": "...", "fieldId": "...", "value": ..., "version": 1 }` | | ||
@@ -486,2 +485,2 @@ 因此 Skill 在解释“写接口为什么失败”时,必须明确区分: | ||
| - `row/page` 说明时建议优先采用前端真实口径 `keyword / searchFieldIds / filters / filterMatchType / sortRule` | ||
| - `row create`、`row update`、`row set-cell` 仍属于“CLI 已有命令,但请求体与 server 真实接口仍需继续收敛” | ||
| - `row create`、`row update`、`row set-cell` 当前已可按 server 契约写入,但调用前仍需先获取真实 `fieldId` |
| --- | ||
| name: dimens-table | ||
| description: | | ||
| 多维表格技能,覆盖工作表、字段、视图、行数据、系统视图映射和表格相关业务上下文。 | ||
| 维表智联中的多维表格技能,覆盖工作表、字段、视图、行数据、系统视图映射和表格相关业务上下文。 | ||
@@ -16,4 +16,11 @@ **当以下情况时使用此 Skill**: | ||
| 适用产品: | ||
| - 产品名称:`维表智联` | ||
| - 开发方:`方块智联工作室` | ||
| - 官网:[https://dimens.bintelai.com/](https://dimens.bintelai.com/) | ||
| ## 执行前必读 | ||
| - ✅ 执行任何 `project / sheet / column / row / ai` 命令前,先完成认证;认证方式优先参考 `dimens-key-auth` | ||
| - ✅ 表格能力默认要先确认 `projectId`,大多数写操作还需要 `teamId` | ||
@@ -36,5 +43,5 @@ - ✅ 字段、视图、行数据都属于工作表上下文,不能脱离 `sheetId` 单独判断 | ||
| | 查询字段列表 | `dimens-cli column list` | `teamId`, `projectId`, `sheetId` | - | 先确认字段结构 | | ||
| | 创建字段 | `dimens-cli column create` | `teamId`, `projectId`, `sheetId` | `type`, `property`, `uiType` | 字段类型影响值结构 | | ||
| | 创建字段 | `dimens-cli column create` | `teamId`, `projectId`, `sheetId`, `type`, `label` 或兼容参数 `title` | `property`, `uiType`, `config`, `required`, `unique`, `key` | 字段类型影响值结构,推荐优先传 `--label` | | ||
| | 查询行数据 | `dimens-cli row page` | `teamId`, `projectId`, `sheetId` | `viewId`, `page`, `size`, `keyword`, `searchFieldIds`, `filters`, `filterMatchType`, `sortRule` | 行读取统一走分页接口,读取链路会受字段筛选、视图配置和权限共同影响 | | ||
| | 更新单元格 | `dimens-cli row set-cell` | `sheetId`, `rowId`, `fieldId` 或 `fieldName`, `value` | `version` | 写入前先确认字段和值结构 | | ||
| | 更新单元格 | `dimens-cli row set-cell` | `sheetId`, `rowId`, `fieldId`, `value` | `version`, `columnId` | 服务端真实契约以 `fieldId` 为准,`columnId` 仅兼容旧 CLI 习惯 | | ||
@@ -76,11 +83,13 @@ ## 核心约束 | ||
| | 文档 | 作用 | 什么时候必须看 | | ||
| | Skill / references | 作用 | 什么时候必须看 | | ||
| | --- | --- | --- | | ||
| | `AGENTS.md` | 仓库总规则、模块定位、文档优先级 | 每次处理本仓库都要先看 | | ||
| | `.trae/已开发文档/字段类型管理.md` | 字段类型、系统视图字段、项目绑定与默认回退 | 处理字段/系统视图时必须看 | | ||
| | `.trae/已开发文档/权限机制架构设计图.md` | 表级、列级、行级权限分层 | 处理写入权限时建议看 | | ||
| | `.trae/已开发文档/权限流程图.md` | 行分页读取 + Yjs 权限链路 | 处理协同与写入问题时建议看 | | ||
| | `.trae/已开发文档/yjs-socket 协作指南.md` | 协同写入、广播过滤和系统字段净化 | 处理协同问题时建议看 | | ||
| | `dimens-cli/文档/业务控制说明.md` | CLI/SDK 与表格接口映射 | 写命令型 Skill 时必须看 | | ||
| | `dimens-cli/文档/cli 命令使用指南.md` | 当前 CLI 真实表格命令入口 | 给命令示例时必须看 | | ||
| | `dimens-key-auth` | 认证、token 复用与第三方接入边界 | 执行任何表格命令前必须先确认 | | ||
| | `dimens-team` | 团队与项目上下文来源 | 进入表域前必须先看 | | ||
| | `dimens-permission` | 表级、列级、行级与协同权限边界 | 处理写入权限时建议看 | | ||
| | `dimens-workflow` | 系统视图字段与工作流入口的映射关系 | 处理 AI 分析、审批、自动化入口时建议看 | | ||
| | `references/field-design-patterns.md` | 字段设计模板、relation 结构 | 设计字段时必须看 | | ||
| | `references/row-filters.md` | `row/page` 搜索、筛选、排序与 `viewId` 继承 | 设计查询案例时必须看 | | ||
| | `references/field-rules.md` | 字段规则和系统视图字段边界 | 处理系统字段时必须看 | | ||
| | `references/build-flow.md` | 表域能力落地流程 | 从零搭表时建议看 | | ||
| | `references/examples.md` | 表 / 字段 / 行接口案例 | 需要直接举例时看 | | ||
@@ -119,3 +128,3 @@ ## 使用场景示例 | ||
| --row-id ROW1 \ | ||
| --field-name 状态 \ | ||
| --field-id fld_status \ | ||
| --value 已完成 | ||
@@ -127,2 +136,3 @@ ``` | ||
| - 写入前要先确认字段类型和值结构 | ||
| - `fieldId` 需要先通过 `dimens-cli column list` 获取,不能直接拿中文字段名当写入键 | ||
| - 如果是系统字段、只读字段或命中行级策略,后端仍可能拒绝 | ||
@@ -129,0 +139,0 @@ |
@@ -58,3 +58,3 @@ # dimens-team 接口案例 | ||
| | 路径 | `/app/org/:teamId/project/page` | | ||
| | 控制器 | `server/src/modules/org/controller/app/project.ts` | | ||
| | 入口角色 | 团队项目分页入口 | | ||
| | 鉴权 | `Authorization: Bearer {token}` | | ||
@@ -145,3 +145,3 @@ | ||
| | 路径 | `/app/org/:teamId/project/info?id=:projectId` | | ||
| | 控制器 | `server/src/modules/org/controller/app/project.ts` | | ||
| | 入口角色 | 团队项目详情入口 | | ||
| | 鉴权 | `Authorization: Bearer {token}` | | ||
@@ -148,0 +148,0 @@ |
@@ -21,3 +21,3 @@ # dimens-team 项目入口说明 | ||
| 在当前系统里,默认应按下面顺序理解业务入口: | ||
| 在维表智联里,默认应按下面顺序理解业务入口: | ||
@@ -24,0 +24,0 @@ 1. 先进入团队 |
| --- | ||
| name: dimens-team | ||
| description: | | ||
| 多维项目中的团队与项目上下文技能,覆盖团队、成员、部门、项目、租户隔离和默认上下文判断。 | ||
| 维表智联中的团队与项目上下文技能,覆盖团队、成员、部门、项目、租户隔离和默认上下文判断。 | ||
@@ -16,2 +16,8 @@ **当以下情况时使用此 Skill**: | ||
| 适用产品: | ||
| - 产品名称:`维表智联` | ||
| - 开发方:`方块智联工作室` | ||
| - 官网:[https://dimens.bintelai.com/](https://dimens.bintelai.com/) | ||
| ## 执行前必读 | ||
@@ -83,10 +89,11 @@ | ||
| | 文档 | 作用 | 什么时候必须看 | | ||
| | Skill / references | 作用 | 什么时候必须看 | | ||
| | --- | --- | --- | | ||
| | `AGENTS.md` | 仓库总规则、模块定位、文档优先级 | 每次处理本仓库都要先看 | | ||
| | `.trae/已开发文档/团队项目管理设计.md` | 团队、项目、部门、角色、隔离边界的核心模型 | 处理团队项目上下文时必须看 | | ||
| | `.trae/已开发文档/权限机制架构设计图.md` | 权限分层与角色边界 | 处理访问范围时建议看 | | ||
| | `.trae/已开发文档/权限流程图.md` | 权限链路与协同边界 | 分析看不到资源时建议看 | | ||
| | `dimens-cli/文档/业务控制说明.md` | CLI/SDK 与团队项目接口映射 | 写命令型 Skill 时必须看 | | ||
| | `dimens-cli/文档/cli 命令使用指南.md` | 当前 CLI 的团队、项目、上下文命令 | 给命令示例时必须看 | | ||
| | `dimens-system-orchestrator` | 系统级任务入口与整体路由 | 处理系统建设任务时建议先看 | | ||
| | `dimens-permission` | 权限分层与资源可见性 | 分析能看不能看时建议看 | | ||
| | `dimens-table` | 表格、文档、字段、行数据会继承项目上下文 | 进入表域前建议看 | | ||
| | `references/context-sources.md` | 显式参数、profile、环境变量三类上下文来源 | 处理上下文覆盖时必须看 | | ||
| | `references/project-entry.md` | 如何从团队进入项目资源 | 判断项目入口时必须看 | | ||
| | `references/isolation.md` | 团队与项目隔离边界 | 处理跨团队、跨项目问题时必须看 | | ||
| | `references/examples.md` | 团队 / 项目典型问题案例 | 需要快速举例时看 | | ||
@@ -93,0 +100,0 @@ ## 使用场景示例 |
| # dimens-workflow 接口案例 | ||
| 本文档聚焦当前仓库里最明确、且已由 `dimens-cli` 对接的工作流接口:OpenAI 兼容聊天接口。 | ||
| 本文档聚焦维表智联当前最明确、且已由 `dimens-cli` 对接的工作流接口:OpenAI 兼容聊天接口。 | ||
@@ -24,3 +24,3 @@ 同时补充项目入口、模型解析和返回格式案例,保证 Skill 在解释工作流问题时不会只停留在概念层。 | ||
| | 路径 | `/app/flow/:teamId/v1/chat/completions` | | ||
| | 控制器 | `server/src/modules/flow/controller/app/chat.ts` | | ||
| | 入口角色 | 工作流聊天兼容入口 | | ||
| | 中间件 | `FlowTeamMiddleware` | | ||
@@ -87,3 +87,3 @@ | 鉴权 | `Authorization: Bearer {token}` | | ||
| Skill 必须明确说明当前控制器里的真实判断: | ||
| Skill 必须明确说明当前接口实现里的真实判断: | ||
@@ -90,0 +90,0 @@ #### 默认模型请求 |
@@ -16,3 +16,3 @@ # dimens-workflow 模型路由说明 | ||
| 基于当前仓库文档与代码结论: | ||
| 基于当前 Skill 体系已确认的实现结论: | ||
@@ -19,0 +19,0 @@ - 团队默认模型管理页面已存在 |
| --- | ||
| name: dimens-workflow | ||
| description: | | ||
| 多维项目中的 AI 工作流技能,覆盖团队工作流定义、项目工作流挂载、运行调用、默认模型与节点模型配置边界。 | ||
| 维表智联中的 AI 工作流技能,覆盖团队工作流定义、项目工作流挂载、运行调用、默认模型与节点模型配置边界。 | ||
@@ -16,2 +16,8 @@ **当以下情况时使用此 Skill**: | ||
| 适用产品: | ||
| - 产品名称:`维表智联` | ||
| - 开发方:`方块智联工作室` | ||
| - 官网:[https://dimens.bintelai.com/](https://dimens.bintelai.com/) | ||
| ## 执行前必读 | ||
@@ -70,11 +76,12 @@ | ||
| | 文档 | 作用 | 什么时候必须看 | | ||
| | Skill / references | 作用 | 什么时候必须看 | | ||
| | --- | --- | --- | | ||
| | `AGENTS.md` | 仓库总规则、模块定位、文档优先级 | 每次处理本仓库都要先看 | | ||
| | `.trae/已开发文档/工作流架构设计.md` | 工作流前后端整体架构、协议、执行链路 | 处理工作流时必须看 | | ||
| | `.trae/已开发文档/模型使用文档.md` | 模型供应商、默认回退与节点显式配置策略 | 处理模型配置时必须看 | | ||
| | `.trae/使用方案/工作流的使用方案.md` | 当前代码里的真实工作流管理与使用入口 | 解释真实现状时必须看 | | ||
| | `.trae/已开发文档/团队项目管理设计.md` | 团队与项目隔离模型 | 分析项目挂载、团队边界时必须看 | | ||
| | `dimens-cli/文档/业务控制说明.md` | CLI/SDK 与后端能力映射 | 写命令型 Skill 时必须看 | | ||
| | `dimens-cli/文档/cli 命令使用指南.md` | 当前 CLI 真实命令入口 | 需要给命令示例时必须看 | | ||
| | `dimens-team` | 团队与项目上下文边界 | 分析项目挂载时必须看 | | ||
| | `dimens-table` | 系统视图、项目内入口与表域联动 | 分析 AI 分析入口时建议看 | | ||
| | `dimens-permission` | 项目可见性、角色与资源授权边界 | 处理看不到或不能运行时建议看 | | ||
| | `references/usage.md` | 团队定义 / 项目挂载 / 运行调用三层分层 | 处理工作流时必须看 | | ||
| | `references/project-binding.md` | 项目挂载与系统视图入口关系 | 分析项目里看不到时必须看 | | ||
| | `references/model-routing.md` | 默认模型与节点模型边界 | 处理模型配置时必须看 | | ||
| | `references/capability-status.md` | 已封装 / server-only / 部分对齐 状态 | 判断当前能力范围时建议看 | | ||
| | `references/examples.md` | 工作流接口案例 | 需要直接举例时看 | | ||
@@ -81,0 +88,0 @@ ## 使用场景示例 |
+81
-162
@@ -1,23 +0,51 @@ | ||
| # Dimens CLI Skills | ||
| # 维表智联 Skill 体系 | ||
| ## 1. 文档目标 | ||
| ## 1. 技能体系定位 | ||
| 本文档是 `dimens-cli/skills/` 的总入口,用来统一说明: | ||
| 这里是 `dimens-cli/skills/` 的独立 Skill 体系总入口。 | ||
| 1. 当前已经落了哪些技能 | ||
| 2. 每个技能分别解决什么问题 | ||
| 3. 什么时候该优先使用哪个技能 | ||
| 4. 技能与 CLI 命令、SDK、业务文档之间是什么关系 | ||
| 这套 Skill 体系只服务于一个产品: | ||
| 这份文档面向两类读者: | ||
| - 产品名称:`维表智联` | ||
| - 开发方:`方块智联工作室` | ||
| - 官网:[https://dimens.bintelai.com/](https://dimens.bintelai.com/) | ||
| - 维护 `dimens-cli` 技能体系的开发者 | ||
| - 在技能发现、技能调度、提示语设计时需要快速定位的 AI | ||
| 这套体系的核心约束只有两条: | ||
| --- | ||
| 1. Skill 内部不要再引用外部文档体系 | ||
| 2. 只能通过 Skill 与 Skill 之间互相路由、互相引用 | ||
| ## 2. 当前技能总览 | ||
| 也就是说: | ||
| 当前 `dimens-cli/skills/` 已落地 7 个正式技能: | ||
| - 不再把外部规则文档当成 Skill 的前置依赖 | ||
| - Skill 自己就是一套独立的产品操作知识体系 | ||
| ## 2. 使用前提 | ||
| 这些 Skill 默认建立在 `dimens-cli` 已可用的前提下。 | ||
| 如果本地还没有 `dimens-cli` 命令,需要先安装: | ||
| ```bash | ||
| npm install -g @bintel/dimens-cli | ||
| ``` | ||
| 或: | ||
| ```bash | ||
| npm install @bintel/dimens-cli | ||
| ``` | ||
| 或: | ||
| ```bash | ||
| pnpm add @bintel/dimens-cli | ||
| ``` | ||
| 只有当 `@bintel/dimens-cli` 已安装,并且本地能执行 `dimens-cli` 或 `node ./bin/dimens-cli.js` 时,这些 Skill 里的命令、案例和映射才成立。 | ||
| ## 3. 当前 Skill 总览 | ||
| 当前 `维表智联` 的 Skill 体系已落地 7 个正式技能: | ||
| | Skill | 业务域 | 什么时候优先用 | | ||
@@ -33,20 +61,18 @@ | --- | --- | --- | | ||
| --- | ||
| ## 4. 默认路由顺序 | ||
| ## 3. 推荐使用顺序 | ||
| 很多问题不是单 Skill 能独立解释的,建议按下面顺序判断。 | ||
| ### 3.1 系统级任务优先 | ||
| ### 4.1 系统级任务优先 | ||
| 如果用户的问题是: | ||
| - “帮我生成一个客户管理系统” | ||
| - “帮我做一个项目管理平台” | ||
| - “搭一个审批系统” | ||
| - “生成一个业务系统” | ||
| - 帮我生成一个客户管理系统 | ||
| - 帮我做一个项目管理平台 | ||
| - 搭一个审批系统 | ||
| - 生成一个业务系统 | ||
| 优先从 `dimens-system-orchestrator` 入手。 | ||
| ### 3.2 上下文优先 | ||
| ### 4.2 上下文优先 | ||
@@ -61,14 +87,4 @@ 如果用户的问题里没有明确: | ||
| ### 3.3 权限优先 | ||
| ### 4.3 资源域优先 | ||
| 如果现象是: | ||
| - 能看不能改 | ||
| - 某人能看到,某人看不到 | ||
| - 列表正常但协同不正常 | ||
| 优先从 `dimens-permission` 入手。 | ||
| ### 3.4 资源域优先 | ||
| 如果资源对象已经明确,再切到具体业务 Skill: | ||
@@ -82,8 +98,7 @@ | ||
| | 工作表 / 字段 / 行 / 视图 | `dimens-table` | | ||
| | 权限 / 公开访问 / 协同越权 | `dimens-permission` | | ||
| | 报表 / 图表 / 参数 / 数据源 | `dimens-report` | | ||
| --- | ||
| ## 5. 技能目录结构 | ||
| ## 4. 技能目录结构 | ||
| 当前目录结构遵循“主 Skill + references”的组织方式: | ||
@@ -94,2 +109,4 @@ | ||
| ├── README.md | ||
| ├── references/ | ||
| │ └── cli-api-catalog.md | ||
| ├── dimens-system-orchestrator/ | ||
@@ -118,3 +135,3 @@ │ ├── SKILL.md | ||
| ### 4.1 `SKILL.md` 的职责 | ||
| ### 5.1 `SKILL.md` 的职责 | ||
@@ -127,6 +144,6 @@ 每个主 `SKILL.md` 负责: | ||
| - 给出核心约束 | ||
| - 给出必查文档 | ||
| - 给出必查 Skill | ||
| - 给出高频使用场景 | ||
| ### 4.2 `references/` 的职责 | ||
| ### 5.2 `references/` 的职责 | ||
@@ -141,135 +158,37 @@ `references/` 用来承接: | ||
| 以 `dimens-table` 为例,当前已经拆成: | ||
| ## 6. Skill 之间如何互相调用 | ||
| - `references/examples.md`:接口级案例总览 | ||
| - `references/field-design-patterns.md`:字段设计模板、字段分层、relation 设计 | ||
| - `references/row-filters.md`:`row/page` 搜索、筛选、排序、`viewId` 继承案例 | ||
| - `references/field-rules.md`:系统视图规则和字段规则总引用 | ||
| 这是一个独立 Skill 体系,所以默认只允许 Skill 之间互相路由。 | ||
| ### 4.3 总索引 | ||
| 推荐理解方式: | ||
| 为避免“各 Skill 各自很细,但整体容易遗漏接口”,当前统一增加总索引: | ||
| | 当前问题 | 优先进入 | | ||
| | --- | --- | | ||
| | 先拆系统、再决定做哪些模块 | `dimens-system-orchestrator` | | ||
| | 先确认团队、项目、上下文 | `dimens-team` | | ||
| | 先设计表、字段、关联、row/page | `dimens-table` | | ||
| | 解释谁能看、谁能改、协同为什么异常 | `dimens-permission` | | ||
| | 解释工作流、默认模型、AI 分析 | `dimens-workflow` | | ||
| | 解释图表、看板、数据源、参数联动 | `dimens-report` | | ||
| | 解释 Key 登录、token 复用、第三方接入 | `dimens-key-auth` | | ||
| - `references/cli-api-catalog.md` | ||
| ## 7. Skill 体系的产品统一口径 | ||
| 这份索引的职责是: | ||
| 后续新增或修改 Skill 时,统一使用以下产品口径: | ||
| - 汇总 `server` 真实接口 | ||
| - 标记哪些已被 CLI 封装 | ||
| - 标记哪些仍是 `server-only` | ||
| - 给出每个业务域的关键入参 / 出参 | ||
| - 明确当前实现与 CLI 封装差异 | ||
| - 产品名称:`维表智联` | ||
| - 开发方:`方块智联工作室` | ||
| - 官网:[https://dimens.bintelai.com/](https://dimens.bintelai.com/) | ||
| ### 4.4 Skill references 分层清单 | ||
| 不要再混用模糊名称作为主产品名。 | ||
| 总原则:主 `SKILL.md` 不承载所有细节,`references/` 按职责拆层。默认先读“主案例层(`examples.md`)”,再按问题类型下钻到专题层。 | ||
| ## 8. 当前推荐阅读顺序 | ||
| | Skill | 主 `examples.md` 职责 | 其他 references 分层职责 | 默认阅读层级 | | ||
| | --- | --- | --- | --- | | ||
| | `dimens-system-orchestrator` | 系统级任务案例总览,统一“系统目标 → 模块拆解 → 子 Skill 路由 → 执行顺序”的落地样例 | `system-decomposition.md`:系统拆解方法与模块边界;`skill-routing.md`:跨 Skill 路由规则与分发顺序;`interface-navigation.md`:从系统任务映射到接口/命令入口的导航 | 先读 `examples.md`,再按问题进入拆解层、路由层、接口导航层 | | ||
| | `dimens-team` | 团队/项目上下文相关高频案例,覆盖“看不到资源、上下文错位、切换失败”等典型问题 | `context-sources.md`:上下文来源与判定优先级;`project-entry.md`:项目入口与定位路径;`isolation.md`:团队与项目隔离边界、越界风险点 | 先读 `examples.md`,再按问题进入上下文来源层、项目入口层、隔离规则层 | | ||
| | `dimens-table` | 表/字段/视图/行操作的接口级案例总览,作为表域问题的首个入口 | `field-design-patterns.md`:字段设计模板与 relation 结构;`row-filters.md`:`row/page` 搜索筛选排序与 `viewId` 继承;`field-rules.md`:系统视图字段与字段规则总引用;`build-flow.md`:表域能力落地流程与执行路径 | 先读 `examples.md`,再按问题进入字段设计层、行筛选层、字段规则层、流程层 | | ||
| | `dimens-workflow` | 工作流运行入口与聊天兼容调用的接口级案例总览 | `usage.md`:团队定义 / 项目挂载 / 运行调用三层分层;`project-binding.md`:团队定义与项目挂载、系统视图入口关系;`model-routing.md`:模型路由与默认模型边界;`capability-status.md`:已封装 / server-only / 部分对齐 状态 | 先读 `examples.md`,再按问题进入使用分层、项目挂载层、模型路由层、能力状态层 | | ||
| ### 4.5 全 Skill 成熟度与默认阅读路径 | ||
| 不同 Skill 的默认阅读路径并不完全相同,但统一遵循“主案例层 → 专题层”的原则:先用 `examples.md` 建立问题定位,再进入对应专题文件完成规则校准与实现细节确认。 | ||
| | Skill | 当前文档成熟度 | 默认先读哪一层 | 再读哪一层 | | ||
| | --- | --- | --- | --- | | ||
| | `dimens-system-orchestrator` | 已分层稳定 | 主案例层:`references/examples.md`(系统任务总览) | 专题层:`system-decomposition.md` → `skill-routing.md` → `interface-navigation.md` | | ||
| | `dimens-team` | 已分层稳定 | 主案例层:`references/examples.md`(上下文与资源可见性案例) | 专题层:`context-sources.md` → `project-entry.md` → `isolation.md` | | ||
| | `dimens-table` | 已分层稳定 | 主案例层:`references/examples.md`(表/字段/视图/行接口案例) | 专题层:`field-design-patterns.md` → `row-filters.md` → `field-rules.md` → `build-flow.md` | | ||
| | `dimens-workflow` | 已分层稳定 | 主案例层:`references/examples.md`(运行入口与调用案例) | 专题层:`usage.md` → `project-binding.md` → `model-routing.md` → `capability-status.md` | | ||
| | `dimens-permission` | 已分层稳定 | 主案例层:`references/examples.md`(权限问题排查案例) | 专题层:按问题下钻准入、表/列/行权限与协同广播规则专题 | | ||
| | `dimens-report` | 已分层稳定 | 主案例层:`references/examples.md`(报表/图表/参数案例) | 专题层:按问题下钻数据源、参数联动、权限展示链路专题 | | ||
| | `dimens-key-auth` | 已分层稳定 | 主案例层:`references/examples.md`(Key 登录与 token 复用案例) | 专题层:`login-flow.md` → `integration-boundaries.md` → `capability-status.md` | | ||
| --- | ||
| ## 5. 技能与 CLI/SDK/文档的关系 | ||
| `dimens-cli` 的 Skill 不是孤立文档,而是四层映射的一部分: | ||
| | 层级 | 作用 | 例子 | | ||
| | --- | --- | --- | | ||
| | Skill | 定义业务域和提示语边界 | `dimens-table` | | ||
| | CLI 命令 | 面向终端用户的操作入口 | `dimens-cli row page` | | ||
| | SDK | 面向代码调用的稳定入口 | `rowSdk.page(...)` | | ||
| | 文档 | 给出规则与真值来源 | `.trae/已开发文档/*`、`dimens-cli/文档/*` | | ||
| 这意味着: | ||
| - Skill 不只是“命令帮助” | ||
| - Skill 也不只是“后端接口清单” | ||
| - Skill 的职责是把业务语义、调用入口和文档真值统一起来 | ||
| - `references/cli-api-catalog.md` 则负责从全局维度防止遗漏接口 | ||
| --- | ||
| ## 6. 当前技能发现机制 | ||
| 当前 `src/skills` 已支持从 `skills/` 目录自动发现 Skill: | ||
| 1. 遍历 `skills/*/SKILL.md` | ||
| 2. 读取 frontmatter 中的 `name` 与 `description` | ||
| 3. 自动附带 `skillPath` 和 `references/` 文件列表 | ||
| 这意味着后续新增 Skill 时: | ||
| - 只要目录结构符合约定 | ||
| - 并且 `SKILL.md` frontmatter 完整 | ||
| 就可以被 `src/skills` 自动发现,不需要继续手工维护技能常量清单。 | ||
| --- | ||
| ## 7. 开发约束 | ||
| 新增 Skill 时,建议固定遵守下面几条: | ||
| 1. 目录名与 frontmatter `name` 保持一致 | ||
| 2. 主文件固定叫 `SKILL.md` | ||
| 3. 超长内容拆进 `references/` | ||
| 4. 技能文档必须显式引用 `AGENTS.md`、`.trae` 文档和 `dimens-cli/文档` | ||
| 5. 不要把不同业务域硬塞进同一个 Skill | ||
| --- | ||
| ## 8. 系统级 Skill 的核心地位 | ||
| 当前这批 Skill 里,`dimens-system-orchestrator` 是系统建设类需求的总入口。 | ||
| 当用户的表达是: | ||
| - “帮我生成一个客户管理系统” | ||
| - “帮我做一个项目管理平台” | ||
| - “帮我搭一个审批系统” | ||
| - “生成一个业务系统” | ||
| 不应该直接跳进单个业务 Skill,而应该先由 `dimens-system-orchestrator` 做: | ||
| 1. 系统目标识别 | ||
| 2. 模块拆解 | ||
| 3. 子 Skill 路由 | ||
| 4. 执行顺序规划 | ||
| 5. 风险与待确认项输出 | ||
| 只有当这一步稳定后,才继续进入 `dimens-team`、`dimens-table`、`dimens-permission`、`dimens-workflow`、`dimens-report`、`dimens-key-auth` 等业务 Skill。 | ||
| ## 9. 后续建议 | ||
| 如果继续扩展技能体系,建议优先做两类增强: | ||
| 1. 继续强化系统级 Skill 与业务 Skill 的联动说明,让“先总控、后分发”的路径更稳定 | ||
| 2. 在工具层逐步把 Skill 与真实 Tool、SDK 调用做自动映射,而不是只停留在文档发现阶段 | ||
| 当前这份 `README.md` 的作用,就是先把现有 7 个技能的入口、分层和系统级总控关系固定下来,避免后续继续扩展时再次失控。 | ||
| ## 10. 当前接口级覆盖入口 | ||
| 当前建议按下面顺序查: | ||
| 1. 先看本 README 确认 Skill 归属。 | ||
| 2. 再看 `references/cli-api-catalog.md` 确认接口是否已覆盖、是否已 CLI 封装。 | ||
| 3. 最后进入对应 Skill 的 `references/examples.md` 查看字段级入参 / 出参与案例。 | ||
| 1. 先看本 README,确认问题落在哪个 Skill | ||
| 2. 如果是系统建设类需求,先看 `dimens-system-orchestrator` | ||
| 3. 如果是团队和项目边界问题,先看 `dimens-team` | ||
| 4. 如果是表、字段、row/page 问题,先看 `dimens-table` | ||
| 5. 如果是工作流、权限、报表、Key 接入问题,再进入对应业务 Skill | ||
| 6. 需要接口级细节时,再继续看对应 Skill 下的 `references/*.md` |
@@ -1,2 +0,2 @@ | ||
| # Dimens CLI Skill API 总目录 | ||
| # 维表智联 Skill API 总目录 | ||
@@ -6,7 +6,13 @@ 本文档把当前 `dimens-cli/skills` 覆盖到的真实接口按业务域汇总,目标是解决两类问题: | ||
| 1. Skill references 很多,但主入口不容易快速确认“哪些接口已经覆盖” | ||
| 2. `server` 真实接口、CLI 已封装命令、仍未封装的能力容易混淆 | ||
| 2. 平台真实接口、CLI 已封装命令、仍未封装的能力容易混淆 | ||
| 适用产品统一口径: | ||
| - 产品名称:`维表智联` | ||
| - 开发方:`方块智联工作室` | ||
| - 官网:[https://dimens.bintelai.com/](https://dimens.bintelai.com/) | ||
| 统一口径: | ||
| - `server 接口` 指当前仓库里可对照到的真实 HTTP / WebSocket 入口 | ||
| - `平台接口` 指维表智联当前对外可访问的真实 HTTP / WebSocket 入口 | ||
| - `CLI 命令` 指当前 `dimens-cli` 已有的真实命令 | ||
@@ -18,3 +24,3 @@ - `状态` 分为 `已封装`、`server-only`、`部分对齐` | ||
| | 业务动作 | server 接口 | 方法 | CLI 命令 | 状态 | 关键入参 | 关键出参 | | ||
| | 业务动作 | 平台接口 | 方法 | CLI 命令 | 状态 | 关键入参 | 关键出参 | | ||
| | --- | --- | --- | --- | --- | --- | --- | | ||
@@ -36,3 +42,3 @@ | API Key 登录换 token | `/open/user/login/apiKey` | `POST` | `dimens-cli auth api-key-login` | 已封装 | `apiKey`、`apiSecret` | `token`、`refreshToken`、`teamIds` | | ||
| | 业务动作 | server 接口 | 方法 | CLI 命令 | 状态 | 关键入参 | 关键出参 | | ||
| | 业务动作 | 平台接口 | 方法 | CLI 命令 | 状态 | 关键入参 | 关键出参 | | ||
| | --- | --- | --- | --- | --- | --- | --- | | ||
@@ -51,3 +57,3 @@ | 设置默认团队 | 本地 profile 写入 | - | `dimens-cli auth use-team` | 已封装 | `teamId` | profile 中的默认 `teamId` | | ||
| | 业务动作 | server 接口 | 方法 | CLI 命令 | 状态 | 关键入参 | 关键出参 | | ||
| | 业务动作 | 平台接口 | 方法 | CLI 命令 | 状态 | 关键入参 | 关键出参 | | ||
| | --- | --- | --- | --- | --- | --- | --- | | ||
@@ -60,5 +66,5 @@ | 资源列表 | `/app/mul/project/:projectId/sheet/list` | `GET` | `dimens-cli sheet list` | 已封装 | `projectId` | 资源列表、`type`、`permission` | | ||
| | 行详情 | `/app/mul/:teamId/:projectId/sheet/:sheetId/row/info?id=:rowId` | `GET` | `dimens-cli row info` | 已封装 | `teamId`、`projectId`、`sheetId`、`id` | 单行详情 | | ||
| | 行新增 | `row` 控制器真实写接口 | 多种 | `dimens-cli row create` | 部分对齐 | 取决于 body 结构 | 真实接口与 CLI 传参仍需继续收敛 | | ||
| | 行更新 | `row` 控制器真实写接口 | 多种 | `dimens-cli row update` | 部分对齐 | 取决于 body 结构 | 真实接口与 CLI 传参仍需继续收敛 | | ||
| | 单元格写入 | `row` 控制器真实写接口 | 多种 | `dimens-cli row set-cell` | 部分对齐 | `rowId`、字段标识、值 | 真实接口与 CLI 传参仍需继续收敛 | | ||
| | 行新增 | 行写入接口族 | 多种 | `dimens-cli row create` | 部分对齐 | 取决于 body 结构 | 真实接口与 CLI 传参仍需继续收敛 | | ||
| | 行更新 | 行写入接口族 | 多种 | `dimens-cli row update` | 部分对齐 | 取决于 body 结构 | 真实接口与 CLI 传参仍需继续收敛 | | ||
| | 单元格写入 | 行写入接口族 | 多种 | `dimens-cli row set-cell` | 部分对齐 | `rowId`、字段标识、值 | 真实接口与 CLI 传参仍需继续收敛 | | ||
@@ -72,3 +78,3 @@ 参考: | ||
| | 业务动作 | server 接口 | 方法 | CLI 命令 | 状态 | 关键入参 | 关键出参 | | ||
| | 业务动作 | 平台接口 | 方法 | CLI 命令 | 状态 | 关键入参 | 关键出参 | | ||
| | --- | --- | --- | --- | --- | --- | --- | | ||
@@ -79,4 +85,4 @@ | OpenAI 兼容聊天 | `/app/flow/:teamId/v1/chat/completions` | `POST` | `dimens-cli ai chat-completions` | 已封装 | `teamId`、`messages`、可选 `model`、`stream` | `chat.completion` 或 SSE chunk | | ||
| | 开放工作流执行 | `/open/flow/run/invoke` | `POST` | 无 | server-only | `flowId` / `label`、开放侧上下文 | 执行结果 | | ||
| | 团队工作流管理 | `flow info` 相关控制器 | 多种 | 无 | server-only | `teamId`、工作流定义参数 | 工作流定义、发布信息 | | ||
| | 项目工作流挂载 | `workflow binding` 相关接口 | 多种 | 无 | server-only | `teamId`、`projectId`、`systemView` 等 | 项目可见工作流及树结构 | | ||
| | 团队工作流管理 | 工作流定义与发布接口族 | 多种 | 无 | server-only | `teamId`、工作流定义参数 | 工作流定义、发布信息 | | ||
| | 项目工作流挂载 | 工作流挂载与绑定接口族 | 多种 | 无 | server-only | `teamId`、`projectId`、`systemView` 等 | 项目可见工作流及树结构 | | ||
@@ -91,3 +97,3 @@ 参考: | ||
| | 业务动作 | server 接口 | 方法 | CLI 命令 | 状态 | 关键入参 | 关键出参 | | ||
| | 业务动作 | 平台接口 | 方法 | CLI 命令 | 状态 | 关键入参 | 关键出参 | | ||
| | --- | --- | --- | --- | --- | --- | --- | | ||
@@ -111,3 +117,3 @@ | 查询我的权限快照 | `/app/mul/project/:projectId/permission/myPermissions` | `GET` | 无 | server-only | `projectId` | `roles`、`effectiveCanRead`、`effectiveCanWrite` | | ||
| | 业务动作 | server 接口 | 方法 | CLI 命令 | 状态 | 关键入参 | 关键出参 | | ||
| | 业务动作 | 平台接口 | 方法 | CLI 命令 | 状态 | 关键入参 | 关键出参 | | ||
| | --- | --- | --- | --- | --- | --- | --- | | ||
@@ -123,3 +129,3 @@ | 报表列表 | `/app/report/:projectId/list` | `POST` | 无 | server-only | `projectId`、可选 `keyword`、`type`、`status`、分页 | 报表分页结果 | | ||
| | 模板列表/详情/应用 | `/app/report/template/*` | `POST` / `GET` | 无 | server-only | 分类、关键字、`templateId`、`projectId` | 模板列表、应用后的 `reportId` | | ||
| | 版本列表/恢复 | `version` 控制器相关接口 | 多种 | 无 | server-only | `reportId`、版本标识 | 版本快照、恢复结果 | | ||
| | 版本列表/恢复 | 报表版本接口族 | 多种 | 无 | server-only | `reportId`、版本标识 | 版本快照、恢复结果 | | ||
@@ -134,6 +140,6 @@ 参考: | ||
| 1. 先写清楚这是 `CLI 命令`、`server 真实接口`,还是两者都有。 | ||
| 1. 先写清楚这是 `CLI 命令`、`平台真实接口`,还是两者都有。 | ||
| 2. 必须至少写出方法、路径、关键入参、关键出参。 | ||
| 3. 不能把尚未封装的 `server` 接口伪装成已有 CLI 能力。 | ||
| 3. 不能把尚未封装的平台接口伪装成已有 CLI 能力。 | ||
| 4. 如果实测结果与文档或抽象设计有差异,必须显式标注“当前实现”。 | ||
| 5. 表格写接口、工作流管理接口、报表接口目前很多仍属于 `server-only`,说明时要保持这个边界。 |
| import { t as __exportAll } from "./rolldown-runtime-95iHPtFO.mjs"; | ||
| import { n as logger } from "./logger-CEOtAYhF.mjs"; | ||
| import { a as AuthSDK, i as ColumnSDK, l as getVersion, n as RowSDK, o as DimensClient, r as ProjectSDK, s as FlowChatSDK, t as SheetSDK } from "./sheet-DafechaB.mjs"; | ||
| import { readFile, writeFile } from "fs/promises"; | ||
| import { join } from "path"; | ||
| import { homedir } from "os"; | ||
| import { existsSync, readFileSync, readdirSync, statSync } from "node:fs"; | ||
| import { dirname as dirname$1, join as join$1, relative, resolve } from "node:path"; | ||
| import { fileURLToPath } from "node:url"; | ||
| //#region src/core/config.ts | ||
| /** | ||
| * 配置管理 | ||
| */ | ||
| const DEFAULT_CONFIG = { | ||
| version: "1.0.0", | ||
| profile: {}, | ||
| skills: {}, | ||
| preferences: {} | ||
| }; | ||
| var ConfigManager = class { | ||
| configPath; | ||
| config; | ||
| constructor() { | ||
| this.configPath = join(homedir(), ".dimens-cli", "config.json"); | ||
| this.config = DEFAULT_CONFIG; | ||
| } | ||
| async load() { | ||
| try { | ||
| const data = await readFile(this.configPath, "utf-8"); | ||
| const parsed = JSON.parse(data); | ||
| this.config = { | ||
| ...DEFAULT_CONFIG, | ||
| ...parsed, | ||
| profile: { | ||
| ...DEFAULT_CONFIG.profile, | ||
| ...parsed.profile || {} | ||
| }, | ||
| skills: parsed.skills || {}, | ||
| preferences: parsed.preferences || {} | ||
| }; | ||
| logger.debug("配置加载成功", { path: this.configPath }); | ||
| } catch (error) { | ||
| logger.debug("配置文件不存在,使用默认配置"); | ||
| this.config = { | ||
| ...DEFAULT_CONFIG, | ||
| profile: { ...DEFAULT_CONFIG.profile } | ||
| }; | ||
| } | ||
| } | ||
| async save() { | ||
| try { | ||
| const { mkdir } = await import("fs/promises"); | ||
| await mkdir(join(homedir(), ".dimens-cli"), { recursive: true }); | ||
| await writeFile(this.configPath, JSON.stringify(this.config, null, 2), "utf-8"); | ||
| logger.debug("配置保存成功", { path: this.configPath }); | ||
| } catch (error) { | ||
| logger.error("配置保存失败", { error: String(error) }); | ||
| throw error; | ||
| } | ||
| } | ||
| get(key) { | ||
| return this.config[key]; | ||
| } | ||
| set(key, value) { | ||
| this.config[key] = value; | ||
| } | ||
| getAll() { | ||
| return { | ||
| ...this.config, | ||
| profile: { ...this.config.profile }, | ||
| skills: { ...this.config.skills }, | ||
| preferences: { ...this.config.preferences } | ||
| }; | ||
| } | ||
| }; | ||
| const config = new ConfigManager(); | ||
| //#endregion | ||
| //#region src/commands/registry.ts | ||
| const registeredCommands = /* @__PURE__ */ new Map(); | ||
| const registeredGroups = /* @__PURE__ */ new Map(); | ||
| const qualifiedCommands = /* @__PURE__ */ new Map(); | ||
| function createCommandGroup(name, description) { | ||
| const group = { | ||
| name, | ||
| description, | ||
| commands: [] | ||
| }; | ||
| registeredGroups.set(name, group); | ||
| return group; | ||
| } | ||
| function registerCommand(command) { | ||
| if (registeredCommands.has(command.name)) logger.warn(`命令 ${command.name} 已存在,将被覆盖`); | ||
| registeredCommands.set(command.name, command); | ||
| if (command.aliases) command.aliases.forEach((alias) => { | ||
| registeredCommands.set(alias, command); | ||
| }); | ||
| logger.debug(`命令已注册: ${command.name}`); | ||
| } | ||
| function registerGroupCommand(groupName, command) { | ||
| (registeredGroups.get(groupName) || createCommandGroup(groupName, groupName)).commands.push(command); | ||
| const qualifiedName = `${groupName}:${command.name}`; | ||
| qualifiedCommands.set(qualifiedName, command); | ||
| if (groupName === "system" || groupName === "auth") { | ||
| registerCommand(command); | ||
| return; | ||
| } | ||
| if (command.aliases) command.aliases.forEach((alias) => { | ||
| qualifiedCommands.set(`${groupName}:${alias}`, command); | ||
| }); | ||
| logger.debug(`命令已注册: ${qualifiedName}`); | ||
| } | ||
| function getCommand(name) { | ||
| return registeredCommands.get(name); | ||
| } | ||
| function getGroupCommand(groupName, commandName) { | ||
| return qualifiedCommands.get(`${groupName}:${commandName}`); | ||
| } | ||
| function getAllCommands() { | ||
| const uniqueCommands = new Set(registeredCommands.values()); | ||
| return Array.from(uniqueCommands); | ||
| } | ||
| function getCommandGroup(name) { | ||
| return registeredGroups.get(name); | ||
| } | ||
| function getAllCommandGroups() { | ||
| return Array.from(registeredGroups.values()); | ||
| } | ||
| function clearCommands() { | ||
| registeredCommands.clear(); | ||
| registeredGroups.clear(); | ||
| qualifiedCommands.clear(); | ||
| logger.debug("所有命令已清除"); | ||
| } | ||
| function createCommand(name, description, handler, options) { | ||
| return { | ||
| name, | ||
| description, | ||
| handler, | ||
| ...options | ||
| }; | ||
| } | ||
| //#endregion | ||
| //#region src/skills/mappings.ts | ||
| const SKILL_MAPPINGS = { | ||
| "dimens-system-orchestrator": { | ||
| version: "1.0.0", | ||
| tags: [ | ||
| "system", | ||
| "orchestrator", | ||
| "planner", | ||
| "routing", | ||
| "builder" | ||
| ], | ||
| commandGroups: ["skill"], | ||
| commands: [ | ||
| "skill recommend", | ||
| "skill info", | ||
| "skill show" | ||
| ], | ||
| sdkModules: [], | ||
| toolNames: ["system_decomposition", "skill_routing"] | ||
| }, | ||
| "dimens-workflow": { | ||
| version: "1.0.0", | ||
| tags: [ | ||
| "workflow", | ||
| "flow", | ||
| "ai", | ||
| "project", | ||
| "team" | ||
| ], | ||
| commandGroups: ["ai"], | ||
| commands: ["ai chat-completions"], | ||
| sdkModules: ["FlowChatSDK", "DimensSDK.ai"], | ||
| toolNames: [ | ||
| "flow_list", | ||
| "project_workflow_binding_list", | ||
| "flow_run_invoke", | ||
| "flow_run_debug", | ||
| "flow_config_get" | ||
| ] | ||
| }, | ||
| "dimens-key-auth": { | ||
| version: "1.0.0", | ||
| tags: [ | ||
| "auth", | ||
| "api-key", | ||
| "token", | ||
| "login", | ||
| "security" | ||
| ], | ||
| commandGroups: ["auth"], | ||
| commands: [ | ||
| "auth api-key-login", | ||
| "auth login", | ||
| "auth refresh", | ||
| "auth status", | ||
| "auth profile" | ||
| ], | ||
| sdkModules: ["AuthSDK", "DimensSDK.auth"], | ||
| toolNames: [ | ||
| "api_key_create", | ||
| "api_key_list", | ||
| "api_key_status", | ||
| "api_key_delete", | ||
| "api_key_reset_secret", | ||
| "api_key_log_page" | ||
| ] | ||
| }, | ||
| "dimens-team": { | ||
| version: "1.0.0", | ||
| tags: [ | ||
| "team", | ||
| "project", | ||
| "tenant", | ||
| "member", | ||
| "context" | ||
| ], | ||
| commandGroups: ["auth", "project"], | ||
| commands: [ | ||
| "auth use-team", | ||
| "auth use-project", | ||
| "project list", | ||
| "project info", | ||
| "project create", | ||
| "project update", | ||
| "project trash", | ||
| "project restore" | ||
| ], | ||
| sdkModules: ["ProjectSDK", "DimensSDK.project"], | ||
| toolNames: [ | ||
| "team_info", | ||
| "team_user_list", | ||
| "project_list", | ||
| "project_info", | ||
| "project_create", | ||
| "project_update", | ||
| "project_trash", | ||
| "project_restore" | ||
| ] | ||
| }, | ||
| "dimens-table": { | ||
| version: "1.0.0", | ||
| tags: [ | ||
| "table", | ||
| "sheet", | ||
| "row", | ||
| "column", | ||
| "view" | ||
| ], | ||
| commandGroups: [ | ||
| "sheet", | ||
| "column", | ||
| "row" | ||
| ], | ||
| commands: [ | ||
| "sheet list", | ||
| "sheet tree", | ||
| "sheet create", | ||
| "sheet info", | ||
| "sheet update", | ||
| "sheet delete", | ||
| "column list", | ||
| "column create", | ||
| "column update", | ||
| "column delete", | ||
| "row page", | ||
| "row info", | ||
| "row create", | ||
| "row update", | ||
| "row delete", | ||
| "row set-cell" | ||
| ], | ||
| sdkModules: [ | ||
| "SheetSDK", | ||
| "ColumnSDK", | ||
| "RowSDK", | ||
| "DimensSDK.sheet", | ||
| "DimensSDK.column", | ||
| "DimensSDK.row" | ||
| ], | ||
| toolNames: [ | ||
| "sheet_list", | ||
| "sheet_info", | ||
| "column_list", | ||
| "column_create", | ||
| "row_page", | ||
| "row_update", | ||
| "row_set_cell" | ||
| ] | ||
| }, | ||
| "dimens-permission": { | ||
| version: "1.0.0", | ||
| tags: [ | ||
| "permission", | ||
| "acl", | ||
| "row-policy", | ||
| "yjs", | ||
| "security" | ||
| ], | ||
| commandGroups: [], | ||
| commands: [], | ||
| sdkModules: [], | ||
| toolNames: [ | ||
| "project_authority_check", | ||
| "permission_resolve", | ||
| "column_permission_resolve", | ||
| "row_policy_check", | ||
| "yjs_permission_snapshot" | ||
| ] | ||
| }, | ||
| "dimens-report": { | ||
| version: "1.0.0", | ||
| tags: [ | ||
| "report", | ||
| "chart", | ||
| "dashboard", | ||
| "parameter", | ||
| "query" | ||
| ], | ||
| commandGroups: [], | ||
| commands: [], | ||
| sdkModules: [], | ||
| toolNames: [ | ||
| "report_list", | ||
| "report_info", | ||
| "report_widget_list", | ||
| "report_parameter_list", | ||
| "report_query", | ||
| "report_export" | ||
| ] | ||
| } | ||
| }; | ||
| function getSkillMapping(name) { | ||
| return SKILL_MAPPINGS[name]; | ||
| } | ||
| //#endregion | ||
| //#region src/skills/index.ts | ||
| /** | ||
| * 技能发现与读取 | ||
| */ | ||
| function getPackageRoot() { | ||
| const currentDir = dirname$1(fileURLToPath(import.meta.url)); | ||
| return [resolve(currentDir, "../"), resolve(currentDir, "../../")].find((candidate) => existsSync(join$1(candidate, "package.json")) && existsSync(join$1(candidate, "skills"))) ?? resolve(currentDir, "../../"); | ||
| } | ||
| function getSkillsRoot() { | ||
| return join$1(getPackageRoot(), "skills"); | ||
| } | ||
| function parseFrontmatter(content) { | ||
| const lines = content.split("\n"); | ||
| if (lines[0]?.trim() !== "---") return {}; | ||
| let i = 1; | ||
| const data = {}; | ||
| while (i < lines.length) { | ||
| const line = lines[i]; | ||
| if (line?.trim() === "---") break; | ||
| if (line?.startsWith("name:")) { | ||
| data.name = line.slice(5).trim(); | ||
| i += 1; | ||
| continue; | ||
| } | ||
| if (line?.startsWith("description:")) { | ||
| const inline = line.slice(12).trim(); | ||
| if (inline && inline !== "|") { | ||
| data.description = inline; | ||
| i += 1; | ||
| continue; | ||
| } | ||
| i += 1; | ||
| const block = []; | ||
| while (i < lines.length) { | ||
| const next = lines[i]; | ||
| if (!next) { | ||
| block.push(""); | ||
| i += 1; | ||
| continue; | ||
| } | ||
| if (!next.startsWith(" ")) break; | ||
| block.push(next.slice(2)); | ||
| i += 1; | ||
| } | ||
| data.description = block.join("\n").trim(); | ||
| continue; | ||
| } | ||
| i += 1; | ||
| } | ||
| return data; | ||
| } | ||
| function listReferenceFiles(referencesDir) { | ||
| if (!existsSync(referencesDir)) return []; | ||
| return readdirSync(referencesDir).filter((file) => file.endsWith(".md")).sort().map((file) => join$1(referencesDir, file)); | ||
| } | ||
| function loadSkillFromDirectory(skillDir) { | ||
| const skillPath = join$1(skillDir, "SKILL.md"); | ||
| if (!existsSync(skillPath) || !statSync(skillPath).isFile()) return; | ||
| const frontmatter = parseFrontmatter(readFileSync(skillPath, "utf8")); | ||
| const name = frontmatter.name?.trim(); | ||
| const description = frontmatter.description?.trim(); | ||
| if (!name || !description) return; | ||
| const referencesDir = join$1(skillDir, "references"); | ||
| const mapping = getSkillMapping(name); | ||
| const skill = { | ||
| name, | ||
| description, | ||
| skillPath, | ||
| references: listReferenceFiles(referencesDir), | ||
| ...mapping | ||
| }; | ||
| if (existsSync(referencesDir)) skill.referencesDir = referencesDir; | ||
| return skill; | ||
| } | ||
| function discoverSkills() { | ||
| const skillsRoot = getSkillsRoot(); | ||
| if (!existsSync(skillsRoot)) return []; | ||
| return readdirSync(skillsRoot).map((entry) => join$1(skillsRoot, entry)).filter((entryPath) => statSync(entryPath).isDirectory()).map(loadSkillFromDirectory).filter((skill) => Boolean(skill)).sort((a, b) => a.name.localeCompare(b.name, "zh-CN")); | ||
| } | ||
| const SKILLS = discoverSkills(); | ||
| function getSkill(name) { | ||
| return SKILLS.find((skill) => skill.name === name); | ||
| } | ||
| function getAllSkills() { | ||
| return [...SKILLS]; | ||
| } | ||
| function getSkillsRootPath() { | ||
| return getSkillsRoot(); | ||
| } | ||
| //#endregion | ||
| //#region src/commands/help.ts | ||
| function findRelatedSkills(groupName, commandName) { | ||
| const qualifiedCommand = commandName ? `${groupName} ${commandName}` : void 0; | ||
| return getAllSkills().filter((skill) => { | ||
| const matchesGroup = skill.commandGroups?.includes(groupName) ?? false; | ||
| const matchesCommand = qualifiedCommand ? skill.commands?.includes(qualifiedCommand) ?? false : false; | ||
| return matchesGroup || matchesCommand; | ||
| }).map((skill) => skill.name).sort((a, b) => a.localeCompare(b, "zh-CN")); | ||
| } | ||
| function printRelatedSkills(groupName, commandName) { | ||
| const relatedSkills = findRelatedSkills(groupName, commandName); | ||
| if (relatedSkills.length === 0) return; | ||
| console.log("相关 Skill:"); | ||
| relatedSkills.forEach((skillName) => { | ||
| console.log(` - ${skillName}`); | ||
| }); | ||
| } | ||
| const helpCommand = { | ||
| name: "help", | ||
| description: "显示帮助信息", | ||
| usage: "help [command] [subcommand]", | ||
| aliases: ["h", "?"], | ||
| handler: async (args) => { | ||
| if (args.length > 0) { | ||
| const groupName = args[0]; | ||
| const commandName = args[1]; | ||
| if (!groupName) return; | ||
| const group = getCommandGroup(groupName); | ||
| if (!group) { | ||
| console.log(`未找到命令组: ${groupName}`); | ||
| return; | ||
| } | ||
| if (commandName) { | ||
| const command = group.commands.find((c) => c.name === commandName || c.aliases?.includes(commandName)); | ||
| if (!command) { | ||
| console.log(`未找到命令: ${groupName} ${commandName}`); | ||
| return; | ||
| } | ||
| console.log(`\n命令: ${group.name} ${command.name}`); | ||
| console.log(`描述: ${command.description}`); | ||
| if (command.usage) console.log(`用法: ${command.usage}`); | ||
| if (command.aliases && command.aliases.length > 0) console.log(`别名: ${command.aliases.join(", ")}`); | ||
| if (command.examples && command.examples.length > 0) { | ||
| console.log("示例:"); | ||
| command.examples.forEach((example) => { | ||
| console.log(` ${example}`); | ||
| }); | ||
| } | ||
| printRelatedSkills(group.name, command.name); | ||
| console.log(""); | ||
| return; | ||
| } | ||
| console.log(`\n命令组: ${group.name}`); | ||
| console.log(`描述: ${group.description}`); | ||
| console.log("可用命令:"); | ||
| group.commands.forEach((command) => { | ||
| console.log(` ${command.name.padEnd(15)} ${command.description}`); | ||
| }); | ||
| printRelatedSkills(group.name); | ||
| console.log(""); | ||
| return; | ||
| } | ||
| console.log("\nDimens CLI - 多维项目开发助手"); | ||
| console.log(`版本: ${getVersion()}\n`); | ||
| console.log("可用命令组:\n"); | ||
| getAllCommandGroups().forEach((group) => { | ||
| console.log(` ${group.name.padEnd(15)} ${group.description}`); | ||
| }); | ||
| console.log("\n使用 \"help [group]\" 查看命令组,使用 \"help [group] [command]\" 查看具体命令"); | ||
| console.log("使用 \"help skill\" 查看技能命令组,使用 \"skill info <name>\" 查看具体 Skill\n"); | ||
| } | ||
| }; | ||
| function registerHelpCommand() { | ||
| createCommandGroup("system", "系统命令"); | ||
| registerGroupCommand("system", helpCommand); | ||
| } | ||
| //#endregion | ||
| //#region src/commands/version.ts | ||
| const versionCommand = { | ||
| name: "version", | ||
| description: "显示版本信息", | ||
| usage: "version", | ||
| aliases: [ | ||
| "v", | ||
| "-v", | ||
| "--version" | ||
| ], | ||
| handler: async () => { | ||
| console.log(`Dimens CLI v${getVersion()}`); | ||
| } | ||
| }; | ||
| function registerVersionCommand() { | ||
| registerGroupCommand("system", versionCommand); | ||
| } | ||
| //#endregion | ||
| //#region src/core/context.ts | ||
| const DEFAULT_BASE_URL = "https://dimens.bintelai.com/api"; | ||
| function resolveContext(args = {}, profile = {}) { | ||
| const context = { output: args.output ?? profile.output ?? "table" }; | ||
| const baseUrl = args.baseUrl ?? process.env.DIMENS_BASE_URL ?? profile.baseUrl ?? "https://dimens.bintelai.com/api"; | ||
| const token = args.token ?? process.env.DIMENS_TOKEN ?? profile.token; | ||
| const refreshToken = args.refreshToken ?? profile.refreshToken; | ||
| const teamId = args.teamId ?? process.env.DIMENS_TEAM_ID ?? profile.teamId; | ||
| const projectId = args.projectId ?? process.env.DIMENS_PROJECT_ID ?? profile.projectId; | ||
| context.baseUrl = baseUrl; | ||
| if (token !== void 0) context.token = token; | ||
| if (refreshToken !== void 0) context.refreshToken = refreshToken; | ||
| if (teamId !== void 0) context.teamId = teamId; | ||
| if (projectId !== void 0) context.projectId = projectId; | ||
| return context; | ||
| } | ||
| //#endregion | ||
| //#region src/core/output.ts | ||
| function formatSuccess(message, data, mode) { | ||
| if (mode === "json") return JSON.stringify({ | ||
| success: true, | ||
| message, | ||
| data | ||
| }, null, 2); | ||
| if (mode === "raw") return [message, typeof data === "string" ? data : JSON.stringify(data)].join("\n"); | ||
| return [message, JSON.stringify(data, null, 2)].join("\n"); | ||
| } | ||
| function formatError(message, mode, options) { | ||
| const relatedSkills = options?.relatedSkills ?? []; | ||
| if (mode === "json") return JSON.stringify({ | ||
| success: false, | ||
| message, | ||
| relatedSkills | ||
| }, null, 2); | ||
| if (relatedSkills.length === 0) return message; | ||
| return [ | ||
| message, | ||
| "", | ||
| "相关 Skill:", | ||
| ...relatedSkills.map((skill) => `- ${skill}`) | ||
| ].join("\n"); | ||
| } | ||
| //#endregion | ||
| //#region src/commands/execution-context.ts | ||
| let currentContext = {}; | ||
| function setExecutionContext(context) { | ||
| currentContext = context; | ||
| } | ||
| function clearExecutionContext() { | ||
| currentContext = {}; | ||
| } | ||
| function getRelatedSkillsForExecutionContext() { | ||
| const { groupName, commandName } = currentContext; | ||
| if (!groupName) return []; | ||
| const qualifiedCommand = commandName ? `${groupName} ${commandName}` : void 0; | ||
| return getAllSkills().filter((skill) => { | ||
| const matchesGroup = skill.commandGroups?.includes(groupName) ?? false; | ||
| const matchesCommand = qualifiedCommand ? skill.commands?.includes(qualifiedCommand) ?? false : false; | ||
| return matchesGroup || matchesCommand; | ||
| }).map((skill) => skill.name).sort((a, b) => a.localeCompare(b, "zh-CN")); | ||
| } | ||
| function getRelatedSkillObjectsForExecutionContext() { | ||
| const relatedSkillNames = new Set(getRelatedSkillsForExecutionContext()); | ||
| return getAllSkills().filter((skill) => relatedSkillNames.has(skill.name)); | ||
| } | ||
| //#endregion | ||
| //#region src/commands/utils.ts | ||
| function parseFlags(args) { | ||
| const flags = {}; | ||
| for (let index = 0; index < args.length; index += 1) { | ||
| const current = args[index]; | ||
| if (!current?.startsWith("--")) continue; | ||
| const normalized = current.slice(2); | ||
| const equalIndex = normalized.indexOf("="); | ||
| if (equalIndex >= 0) { | ||
| const key = normalized.slice(0, equalIndex); | ||
| flags[key] = normalized.slice(equalIndex + 1) || "true"; | ||
| continue; | ||
| } | ||
| const next = args[index + 1]; | ||
| if (next && !next.startsWith("--")) { | ||
| flags[normalized] = next; | ||
| index += 1; | ||
| continue; | ||
| } | ||
| flags[normalized] = "true"; | ||
| } | ||
| return flags; | ||
| } | ||
| function getProfile() { | ||
| return config.get("profile"); | ||
| } | ||
| function saveProfile(profile) { | ||
| config.set("profile", profile); | ||
| return config.save(); | ||
| } | ||
| function mergeProfile(patch) { | ||
| return { | ||
| ...getProfile(), | ||
| ...patch | ||
| }; | ||
| } | ||
| function getContext(flags = {}) { | ||
| const contextArgs = {}; | ||
| if (flags["base-url"]) contextArgs.baseUrl = flags["base-url"]; | ||
| if (flags.token) contextArgs.token = flags.token; | ||
| if (flags["team-id"]) contextArgs.teamId = flags["team-id"]; | ||
| if (flags["project-id"]) contextArgs.projectId = flags["project-id"]; | ||
| if (flags.output === "json" || flags.output === "raw" || flags.output === "table") contextArgs.output = flags.output; | ||
| return resolveContext(contextArgs, getProfile()); | ||
| } | ||
| function createClient(context) { | ||
| if (!context.baseUrl) throw new Error("缺少 baseUrl,请先执行 auth login 或传入 --base-url"); | ||
| const options = { baseUrl: context.baseUrl }; | ||
| if (context.token) options.token = context.token; | ||
| if (context.refreshToken) options.refreshToken = context.refreshToken; | ||
| if (context.teamId) options.teamId = context.teamId; | ||
| if (context.projectId) options.projectId = context.projectId; | ||
| return new DimensClient(options); | ||
| } | ||
| function printSuccess(context, message, data) { | ||
| console.log(formatSuccess(message, data, context.output)); | ||
| } | ||
| function printError(context, error) { | ||
| const message = error instanceof Error ? error.message : String(error); | ||
| const relatedSkills = getRelatedSkillsForExecutionContext(); | ||
| console.log(formatError(message, context.output, { relatedSkills })); | ||
| process.exitCode = 1; | ||
| } | ||
| function requireTeamId(context, flags) { | ||
| const teamId = flags["team-id"] || context.teamId; | ||
| if (!teamId) throw new Error("缺少 teamId,请先执行 auth use-team 或传入 --team-id"); | ||
| return teamId; | ||
| } | ||
| function requireProjectId(context, flags) { | ||
| const projectId = flags["project-id"] || context.projectId; | ||
| if (!projectId) throw new Error("缺少 projectId,请先执行 auth use-project 或传入 --project-id"); | ||
| return projectId; | ||
| } | ||
| function requireSheetId(flags, args) { | ||
| const sheetId = flags["sheet-id"] || args[0]; | ||
| if (!sheetId) throw new Error("缺少 sheetId,请传入 --sheet-id 或 sheet <command> <sheetId>"); | ||
| return sheetId; | ||
| } | ||
| //#endregion | ||
| //#region src/commands/ai/index.ts | ||
| function registerAICommands() { | ||
| createCommandGroup("ai", "AI 对话"); | ||
| registerGroupCommand("ai", createCommand("chat-completions", "调用工作流 OpenAI 兼容聊天接口", async (args) => { | ||
| const flags = parseFlags(args); | ||
| const context = getContext(flags); | ||
| try { | ||
| const teamId = requireTeamId(context, flags); | ||
| const message = flags.message; | ||
| if (!message) throw new Error("缺少 message,请传入 --message"); | ||
| const sdk = new FlowChatSDK(createClient(context)); | ||
| const payload = { | ||
| model: flags.model || "default", | ||
| messages: [{ | ||
| role: "user", | ||
| content: message | ||
| }], | ||
| stream: flags.stream === "true" | ||
| }; | ||
| if (flags.user) payload.user = flags.user; | ||
| printSuccess(context, "AI 对话调用成功", (await sdk.completions(teamId, payload)).data); | ||
| } catch (error) { | ||
| printError(context, error); | ||
| } | ||
| }, { | ||
| usage: "ai chat-completions --message <text> [--model default] [--team-id <teamId>]", | ||
| examples: ["dimens-cli ai chat-completions --message \"你好\" --model default"] | ||
| })); | ||
| } | ||
| //#endregion | ||
| //#region src/commands/auth/index.ts | ||
| function registerAuthCommands() { | ||
| createCommandGroup("auth", "认证与上下文"); | ||
| registerGroupCommand("auth", createCommand("login", "登录并保存本地凭证", async (args) => { | ||
| const flags = parseFlags(args); | ||
| const context = getContext(flags); | ||
| try { | ||
| const username = flags.username; | ||
| const password = flags.password; | ||
| if (!username || !password) throw new Error("缺少登录参数,请传入 --username 和 --password"); | ||
| const result = await new AuthSDK(createClient(context)).login({ | ||
| username, | ||
| password | ||
| }); | ||
| const nextProfile = mergeProfile(context.baseUrl ? { | ||
| baseUrl: context.baseUrl, | ||
| token: result.data.token | ||
| } : { token: result.data.token }); | ||
| if (result.data.refreshToken) nextProfile.refreshToken = result.data.refreshToken; | ||
| await saveProfile(nextProfile); | ||
| printSuccess(context, "登录成功", result.data); | ||
| } catch (error) { | ||
| printError(context, error); | ||
| } | ||
| }, { | ||
| usage: "auth login --username <name> --password <password> [--base-url <url>]", | ||
| examples: ["dimens-cli auth login --username admin --password 123456", "dimens-cli auth login --base-url https://custom.example.com --username admin --password 123456"] | ||
| })); | ||
| registerGroupCommand("auth", createCommand("api-key-login", "使用 apiKey 和 apiSecret 登录并换取 token", async (args) => { | ||
| const flags = parseFlags(args); | ||
| const context = getContext(flags); | ||
| try { | ||
| const apiKey = flags["api-key"]; | ||
| const apiSecret = flags["api-secret"]; | ||
| if (!apiKey || !apiSecret) throw new Error("缺少登录参数,请传入 --api-key 和 --api-secret"); | ||
| const result = await new AuthSDK(createClient(context)).loginByApiKey({ | ||
| apiKey, | ||
| apiSecret | ||
| }); | ||
| const nextProfile = mergeProfile(context.baseUrl ? { | ||
| baseUrl: context.baseUrl, | ||
| token: result.data.token | ||
| } : { token: result.data.token }); | ||
| if (result.data.refreshToken) nextProfile.refreshToken = result.data.refreshToken; | ||
| await saveProfile(nextProfile); | ||
| printSuccess(context, "API Key 登录成功", result.data); | ||
| } catch (error) { | ||
| printError(context, error); | ||
| } | ||
| }, { | ||
| usage: "auth api-key-login --api-key <apiKey> --api-secret <apiSecret> [--base-url <url>]", | ||
| examples: ["dimens-cli auth api-key-login --api-key ak_xxx --api-secret sk_xxx", "dimens-cli auth api-key-login --base-url https://custom.example.com --api-key ak_xxx --api-secret sk_xxx"] | ||
| })); | ||
| registerGroupCommand("auth", createCommand("refresh", "刷新 token", async (args) => { | ||
| const context = getContext(parseFlags(args)); | ||
| try { | ||
| const result = await new AuthSDK(createClient(context)).refreshToken(); | ||
| const nextProfile = mergeProfile({ token: result.data.token }); | ||
| const refreshToken = result.data.refreshToken ?? context.refreshToken; | ||
| if (refreshToken) nextProfile.refreshToken = refreshToken; | ||
| await saveProfile(nextProfile); | ||
| printSuccess(context, "刷新成功", result.data); | ||
| } catch (error) { | ||
| printError(context, error); | ||
| } | ||
| }, { usage: "auth refresh [--base-url <url>]" })); | ||
| registerGroupCommand("auth", createCommand("status", "查看当前上下文", async (args) => { | ||
| const context = getContext(parseFlags(args)); | ||
| printSuccess(context, "当前上下文", context); | ||
| }, { usage: "auth status" })); | ||
| registerGroupCommand("auth", createCommand("use-team", "设置默认团队", async (args) => { | ||
| const context = getContext(); | ||
| try { | ||
| const teamId = args[0]; | ||
| if (!teamId) throw new Error("缺少 teamId,请传入 auth use-team <teamId>"); | ||
| await saveProfile(mergeProfile({ teamId })); | ||
| printSuccess(context, "默认团队已更新", { teamId }); | ||
| } catch (error) { | ||
| printError(context, error); | ||
| } | ||
| }, { usage: "auth use-team <teamId>" })); | ||
| registerGroupCommand("auth", createCommand("use-project", "设置默认项目", async (args) => { | ||
| const context = getContext(); | ||
| try { | ||
| const projectId = args[0]; | ||
| if (!projectId) throw new Error("缺少 projectId,请传入 auth use-project <projectId>"); | ||
| await saveProfile(mergeProfile({ projectId })); | ||
| printSuccess(context, "默认项目已更新", { projectId }); | ||
| } catch (error) { | ||
| printError(context, error); | ||
| } | ||
| }, { usage: "auth use-project <projectId>" })); | ||
| registerGroupCommand("auth", createCommand("profile", "查看本地 profile", async (args) => { | ||
| printSuccess(getContext(parseFlags(args)), "本地 Profile", getProfile()); | ||
| }, { usage: "auth profile" })); | ||
| } | ||
| //#endregion | ||
| //#region src/commands/column/index.ts | ||
| function registerColumnCommands() { | ||
| createCommandGroup("column", "字段管理"); | ||
| registerGroupCommand("column", createCommand("list", "获取字段列表", async (args) => { | ||
| const flags = parseFlags(args); | ||
| const context = getContext(flags); | ||
| try { | ||
| const teamId = requireTeamId(context, flags); | ||
| const projectId = requireProjectId(context, flags); | ||
| const sheetId = requireSheetId(flags, args); | ||
| printSuccess(context, "字段列表获取成功", (await new ColumnSDK(createClient(context)).list(teamId, projectId, sheetId)).data); | ||
| } catch (error) { | ||
| printError(context, error); | ||
| } | ||
| })); | ||
| registerGroupCommand("column", createCommand("create", "创建字段", async (args) => { | ||
| const flags = parseFlags(args); | ||
| const context = getContext(flags); | ||
| try { | ||
| const teamId = requireTeamId(context, flags); | ||
| const projectId = requireProjectId(context, flags); | ||
| const sheetId = requireSheetId(flags, args); | ||
| const title = flags.title; | ||
| if (!title) throw new Error("缺少字段标题,请传入 --title"); | ||
| const sdk = new ColumnSDK(createClient(context)); | ||
| const payload = { title }; | ||
| if (flags.type) payload.type = flags.type; | ||
| printSuccess(context, "字段创建成功", (await sdk.create(teamId, projectId, sheetId, payload)).data); | ||
| } catch (error) { | ||
| printError(context, error); | ||
| } | ||
| })); | ||
| registerGroupCommand("column", createCommand("update", "更新字段", async (args) => { | ||
| const flags = parseFlags(args); | ||
| const context = getContext(flags); | ||
| try { | ||
| const sheetId = requireSheetId(flags, args); | ||
| const fieldId = flags["field-id"] || args[0]; | ||
| if (!fieldId) throw new Error("缺少字段 ID,请传入 --field-id"); | ||
| const sdk = new ColumnSDK(createClient(context)); | ||
| const payload = {}; | ||
| if (flags.title) payload.title = flags.title; | ||
| if (flags.type) payload.type = flags.type; | ||
| printSuccess(context, "字段更新成功", (await sdk.update(sheetId, fieldId, payload)).data); | ||
| } catch (error) { | ||
| printError(context, error); | ||
| } | ||
| })); | ||
| registerGroupCommand("column", createCommand("delete", "删除字段", async (args) => { | ||
| const flags = parseFlags(args); | ||
| const context = getContext(flags); | ||
| try { | ||
| const sheetId = requireSheetId(flags, args); | ||
| const fieldId = flags["field-id"] || args[0]; | ||
| if (!fieldId) throw new Error("缺少字段 ID,请传入 --field-id"); | ||
| printSuccess(context, "字段删除成功", (await new ColumnSDK(createClient(context)).delete(sheetId, fieldId)).data); | ||
| } catch (error) { | ||
| printError(context, error); | ||
| } | ||
| })); | ||
| } | ||
| //#endregion | ||
| //#region src/commands/project/index.ts | ||
| function registerProjectCommands() { | ||
| createCommandGroup("project", "项目管理"); | ||
| registerGroupCommand("project", createCommand("list", "获取项目列表", async (args) => { | ||
| const flags = parseFlags(args); | ||
| const context = getContext(flags); | ||
| try { | ||
| const teamId = requireTeamId(context, flags); | ||
| const sdk = new ProjectSDK(createClient(context)); | ||
| const payload = { | ||
| page: Number(flags.page || "1"), | ||
| size: Number(flags.size || "20") | ||
| }; | ||
| if (flags.keyword) payload.keyword = flags.keyword; | ||
| printSuccess(context, "项目列表获取成功", (await sdk.page(teamId, payload)).data); | ||
| } catch (error) { | ||
| printError(context, error); | ||
| } | ||
| }, { | ||
| usage: "project list [--team-id <teamId>] [--page 1] [--size 20]", | ||
| examples: ["dimens-cli project list --team-id TEAM1"] | ||
| })); | ||
| registerGroupCommand("project", createCommand("info", "获取项目详情", async (args) => { | ||
| const flags = parseFlags(args); | ||
| const context = getContext(flags); | ||
| try { | ||
| const teamId = requireTeamId(context, flags); | ||
| const id = flags.id || args[0]; | ||
| if (!id) throw new Error("缺少项目 ID,请传入 --id 或 project info <id>"); | ||
| printSuccess(context, "项目详情获取成功", (await new ProjectSDK(createClient(context)).info(teamId, id)).data); | ||
| } catch (error) { | ||
| printError(context, error); | ||
| } | ||
| }, { usage: "project info --id <projectId>" })); | ||
| registerGroupCommand("project", createCommand("create", "创建项目", async (args) => { | ||
| const flags = parseFlags(args); | ||
| const context = getContext(flags); | ||
| try { | ||
| const teamId = requireTeamId(context, flags); | ||
| const name = flags.name; | ||
| if (!name) throw new Error("缺少项目名称,请传入 --name"); | ||
| const sdk = new ProjectSDK(createClient(context)); | ||
| const payload = { name }; | ||
| if (flags.remark) payload.remark = flags.remark; | ||
| printSuccess(context, "项目创建成功", (await sdk.create(teamId, payload)).data); | ||
| } catch (error) { | ||
| printError(context, error); | ||
| } | ||
| }, { usage: "project create --name <name>" })); | ||
| registerGroupCommand("project", createCommand("update", "更新项目", async (args) => { | ||
| const flags = parseFlags(args); | ||
| const context = getContext(flags); | ||
| try { | ||
| const teamId = requireTeamId(context, flags); | ||
| const id = flags.id; | ||
| if (!id) throw new Error("缺少项目 ID,请传入 --id"); | ||
| const sdk = new ProjectSDK(createClient(context)); | ||
| const payload = { id }; | ||
| if (flags.name) payload.name = flags.name; | ||
| if (flags.remark) payload.remark = flags.remark; | ||
| printSuccess(context, "项目更新成功", (await sdk.update(teamId, payload)).data); | ||
| } catch (error) { | ||
| printError(context, error); | ||
| } | ||
| }, { usage: "project update --id <projectId> [--name <name>]" })); | ||
| registerGroupCommand("project", createCommand("trash", "将项目移入回收站", async (args) => { | ||
| const flags = parseFlags(args); | ||
| const context = getContext(flags); | ||
| try { | ||
| const teamId = requireTeamId(context, flags); | ||
| const ids = (flags.ids || args.join(",")).split(",").map((item) => item.trim()).filter(Boolean); | ||
| if (ids.length === 0) throw new Error("缺少项目 ID,请传入 --ids P1,P2"); | ||
| printSuccess(context, "项目已移入回收站", (await new ProjectSDK(createClient(context)).trash(teamId, ids)).data); | ||
| } catch (error) { | ||
| printError(context, error); | ||
| } | ||
| }, { usage: "project trash --ids <id1,id2>" })); | ||
| registerGroupCommand("project", createCommand("restore", "恢复项目", async (args) => { | ||
| const flags = parseFlags(args); | ||
| const context = getContext(flags); | ||
| try { | ||
| const teamId = requireTeamId(context, flags); | ||
| const ids = (flags.ids || args.join(",")).split(",").map((item) => item.trim()).filter(Boolean); | ||
| if (ids.length === 0) throw new Error("缺少项目 ID,请传入 --ids P1,P2"); | ||
| printSuccess(context, "项目恢复成功", (await new ProjectSDK(createClient(context)).restore(teamId, ids)).data); | ||
| } catch (error) { | ||
| printError(context, error); | ||
| } | ||
| }, { usage: "project restore --ids <id1,id2>" })); | ||
| registerGroupCommand("project", createCommand("use", "设置默认项目", async (args) => { | ||
| const context = getContext(); | ||
| try { | ||
| const projectId = args[0]; | ||
| if (!projectId) throw new Error("缺少项目 ID,请传入 project use <projectId>"); | ||
| await saveProfile(mergeProfile({ projectId })); | ||
| printSuccess(context, "默认项目已切换", { projectId }); | ||
| } catch (error) { | ||
| printError(context, error); | ||
| } | ||
| }, { usage: "project use <projectId>" })); | ||
| } | ||
| //#endregion | ||
| //#region src/commands/row/index.ts | ||
| function registerRowCommands() { | ||
| createCommandGroup("row", "行数据管理"); | ||
| registerGroupCommand("row", createCommand("page", "分页获取行", async (args) => { | ||
| const flags = parseFlags(args); | ||
| const context = getContext(flags); | ||
| try { | ||
| const teamId = requireTeamId(context, flags); | ||
| const projectId = requireProjectId(context, flags); | ||
| const sheetId = requireSheetId(flags, args); | ||
| const sdk = new RowSDK(createClient(context)); | ||
| const payload = { | ||
| page: Number(flags.page || "1"), | ||
| size: Number(flags.size || "20") | ||
| }; | ||
| printSuccess(context, "行分页获取成功", (await sdk.page(teamId, projectId, sheetId, payload)).data); | ||
| } catch (error) { | ||
| printError(context, error); | ||
| } | ||
| })); | ||
| registerGroupCommand("row", createCommand("info", "获取行详情", async (args) => { | ||
| const flags = parseFlags(args); | ||
| const context = getContext(flags); | ||
| try { | ||
| const teamId = requireTeamId(context, flags); | ||
| const projectId = requireProjectId(context, flags); | ||
| const sheetId = requireSheetId(flags, args); | ||
| const rowId = flags["row-id"] || args[0]; | ||
| if (!rowId) throw new Error("缺少行 ID,请传入 --row-id"); | ||
| printSuccess(context, "行详情获取成功", (await new RowSDK(createClient(context)).info(teamId, projectId, sheetId, rowId)).data); | ||
| } catch (error) { | ||
| printError(context, error); | ||
| } | ||
| })); | ||
| registerGroupCommand("row", createCommand("create", "创建行", async (args) => { | ||
| const flags = parseFlags(args); | ||
| const context = getContext(flags); | ||
| try { | ||
| const sheetId = requireSheetId(flags, args); | ||
| const sdk = new RowSDK(createClient(context)); | ||
| const values = flags.values ? JSON.parse(flags.values) : {}; | ||
| printSuccess(context, "行创建成功", (await sdk.create(sheetId, { values })).data); | ||
| } catch (error) { | ||
| printError(context, error); | ||
| } | ||
| })); | ||
| registerGroupCommand("row", createCommand("update", "更新行", async (args) => { | ||
| const flags = parseFlags(args); | ||
| const context = getContext(flags); | ||
| try { | ||
| const sheetId = requireSheetId(flags, args); | ||
| const rowId = flags["row-id"] || args[0]; | ||
| if (!rowId) throw new Error("缺少行 ID,请传入 --row-id"); | ||
| const version = Number(flags.version || ""); | ||
| if (Number.isNaN(version)) throw new Error("缺少 version,请传入 --version"); | ||
| const values = flags.values ? JSON.parse(flags.values) : {}; | ||
| printSuccess(context, "行更新成功", (await new RowSDK(createClient(context)).update(sheetId, rowId, values, version)).data); | ||
| } catch (error) { | ||
| printError(context, error); | ||
| } | ||
| })); | ||
| registerGroupCommand("row", createCommand("delete", "删除行", async (args) => { | ||
| const flags = parseFlags(args); | ||
| const context = getContext(flags); | ||
| try { | ||
| const sheetId = requireSheetId(flags, args); | ||
| const rowId = flags["row-id"] || args[0]; | ||
| if (!rowId) throw new Error("缺少行 ID,请传入 --row-id"); | ||
| printSuccess(context, "行删除成功", (await new RowSDK(createClient(context)).delete(sheetId, rowId)).data); | ||
| } catch (error) { | ||
| printError(context, error); | ||
| } | ||
| })); | ||
| registerGroupCommand("row", createCommand("set-cell", "更新单元格", async (args) => { | ||
| const flags = parseFlags(args); | ||
| const context = getContext(flags); | ||
| try { | ||
| const sheetId = requireSheetId(flags, args); | ||
| const rowId = flags["row-id"]; | ||
| const columnId = flags["column-id"]; | ||
| if (!rowId || !columnId) throw new Error("缺少 rowId 或 columnId,请传入 --row-id 和 --column-id"); | ||
| printSuccess(context, "单元格更新成功", (await new RowSDK(createClient(context)).updateCell(sheetId, { | ||
| rowId, | ||
| columnId, | ||
| value: flags.value | ||
| })).data); | ||
| } catch (error) { | ||
| printError(context, error); | ||
| } | ||
| })); | ||
| } | ||
| //#endregion | ||
| //#region src/commands/sheet/index.ts | ||
| function registerSheetCommands() { | ||
| createCommandGroup("sheet", "多维表管理"); | ||
| registerGroupCommand("sheet", createCommand("list", "获取表列表", async (args) => { | ||
| const flags = parseFlags(args); | ||
| const context = getContext(flags); | ||
| try { | ||
| const projectId = requireProjectId(context, flags); | ||
| printSuccess(context, "表列表获取成功", (await new SheetSDK(createClient(context)).list(projectId)).data); | ||
| } catch (error) { | ||
| printError(context, error); | ||
| } | ||
| })); | ||
| registerGroupCommand("sheet", createCommand("tree", "获取表树结构", async (args) => { | ||
| const flags = parseFlags(args); | ||
| const context = getContext(flags); | ||
| try { | ||
| const projectId = requireProjectId(context, flags); | ||
| printSuccess(context, "表树获取成功", (await new SheetSDK(createClient(context)).tree(projectId)).data); | ||
| } catch (error) { | ||
| printError(context, error); | ||
| } | ||
| })); | ||
| registerGroupCommand("sheet", createCommand("create", "创建表", async (args) => { | ||
| const flags = parseFlags(args); | ||
| const context = getContext(flags); | ||
| try { | ||
| const projectId = requireProjectId(context, flags); | ||
| const name = flags.name; | ||
| if (!name) throw new Error("缺少表名称,请传入 --name"); | ||
| printSuccess(context, "表创建成功", (await new SheetSDK(createClient(context)).create(projectId, { name })).data); | ||
| } catch (error) { | ||
| printError(context, error); | ||
| } | ||
| })); | ||
| registerGroupCommand("sheet", createCommand("info", "获取表详情", async (args) => { | ||
| const flags = parseFlags(args); | ||
| const context = getContext(flags); | ||
| try { | ||
| const teamId = requireTeamId(context, flags); | ||
| const projectId = requireProjectId(context, flags); | ||
| const sheetId = requireSheetId(flags, args); | ||
| printSuccess(context, "表详情获取成功", (await new SheetSDK(createClient(context)).info(teamId, projectId, sheetId)).data); | ||
| } catch (error) { | ||
| printError(context, error); | ||
| } | ||
| })); | ||
| registerGroupCommand("sheet", createCommand("update", "更新表", async (args) => { | ||
| const flags = parseFlags(args); | ||
| const context = getContext(flags); | ||
| try { | ||
| const teamId = requireTeamId(context, flags); | ||
| const projectId = requireProjectId(context, flags); | ||
| const sheetId = requireSheetId(flags, args); | ||
| const sdk = new SheetSDK(createClient(context)); | ||
| const payload = {}; | ||
| if (flags.name) payload.name = flags.name; | ||
| printSuccess(context, "表更新成功", (await sdk.update(teamId, projectId, sheetId, payload)).data); | ||
| } catch (error) { | ||
| printError(context, error); | ||
| } | ||
| })); | ||
| registerGroupCommand("sheet", createCommand("delete", "删除表", async (args) => { | ||
| const flags = parseFlags(args); | ||
| const context = getContext(flags); | ||
| try { | ||
| const teamId = requireTeamId(context, flags); | ||
| const projectId = requireProjectId(context, flags); | ||
| const sheetId = requireSheetId(flags, args); | ||
| printSuccess(context, "表删除成功", (await new SheetSDK(createClient(context)).delete(teamId, projectId, sheetId)).data); | ||
| } catch (error) { | ||
| printError(context, error); | ||
| } | ||
| })); | ||
| registerGroupCommand("sheet", createCommand("structure", "获取表结构", async (args) => { | ||
| const flags = parseFlags(args); | ||
| const context = getContext(flags); | ||
| try { | ||
| const sheetId = requireSheetId(flags, args); | ||
| printSuccess(context, "表结构获取成功", (await new SheetSDK(createClient(context)).structure(sheetId)).data); | ||
| } catch (error) { | ||
| printError(context, error); | ||
| } | ||
| })); | ||
| } | ||
| //#endregion | ||
| //#region src/commands/skill/index.ts | ||
| function requireSkillName(args) { | ||
| const skillName = args[0]; | ||
| if (!skillName) throw new Error("缺少技能名称,请传入 skill info <name> 或 skill show <name>"); | ||
| return skillName; | ||
| } | ||
| function getSkillOrThrow(name) { | ||
| const skill = getSkill(name); | ||
| if (!skill) throw new Error(`未找到技能: ${name}`); | ||
| return skill; | ||
| } | ||
| function toRelativeSkillPath(filePath) { | ||
| return relative(getSkillsRootPath(), filePath) || filePath; | ||
| } | ||
| function printList(title, items) { | ||
| console.log(`${title}:`); | ||
| if (!items || items.length === 0) { | ||
| console.log(" (无)"); | ||
| return; | ||
| } | ||
| items.forEach((item) => { | ||
| console.log(` - ${item}`); | ||
| }); | ||
| } | ||
| function normalizeSkillForOutput(skill) { | ||
| return { | ||
| ...skill, | ||
| recommendExamples: getRecommendExamples(skill.name), | ||
| skillPath: skill.skillPath ? toRelativeSkillPath(skill.skillPath) : void 0, | ||
| referencesDir: skill.referencesDir ? toRelativeSkillPath(skill.referencesDir) : void 0, | ||
| references: skill.references?.map((reference) => toRelativeSkillPath(reference)) ?? [] | ||
| }; | ||
| } | ||
| function printMapping(skill) { | ||
| printList("命令组", skill.commandGroups); | ||
| printList("命令", skill.commands); | ||
| printList("SDK", skill.sdkModules); | ||
| printList("工具", skill.toolNames); | ||
| } | ||
| const SKILL_RECOMMEND_EXAMPLES = { | ||
| "dimens-system-orchestrator": [ | ||
| "帮我生成一个客户管理系统", | ||
| "帮我做一个项目管理平台", | ||
| "生成一个审批系统" | ||
| ], | ||
| "dimens-workflow": [ | ||
| "工作流 默认模型 AI 分析", | ||
| "审批流程 自动化", | ||
| "flow chat completions" | ||
| ], | ||
| "dimens-key-auth": [ | ||
| "api-key token", | ||
| "api secret 登录", | ||
| "第三方鉴权接入" | ||
| ], | ||
| "dimens-team": [ | ||
| "团队 项目 成员", | ||
| "teamId projectId", | ||
| "租户隔离 项目上下文" | ||
| ], | ||
| "dimens-table": [ | ||
| "多维表格 字段 row", | ||
| "sheet column view", | ||
| "字段类型 系统视图" | ||
| ], | ||
| "dimens-permission": [ | ||
| "行级权限 公开访问 只读", | ||
| "列权限 协同越权", | ||
| "acl 权限" | ||
| ], | ||
| "dimens-report": [ | ||
| "报表 图表 参数筛选", | ||
| "dashboard 数据源", | ||
| "统计看板 导出" | ||
| ] | ||
| }; | ||
| function getRecommendExamples(skillName) { | ||
| return SKILL_RECOMMEND_EXAMPLES[skillName] ?? []; | ||
| } | ||
| function getRecommendQuery(args) { | ||
| const queryParts = []; | ||
| for (let index = 0; index < args.length; index += 1) { | ||
| const current = args[index]; | ||
| if (!current) continue; | ||
| if (current.startsWith("--")) { | ||
| const next = args[index + 1]; | ||
| if (next && !next.startsWith("--")) index += 1; | ||
| continue; | ||
| } | ||
| queryParts.push(current); | ||
| } | ||
| return queryParts.join(" ").trim(); | ||
| } | ||
| const SYSTEM_BUILD_VERBS = [ | ||
| "生成", | ||
| "新建", | ||
| "创建", | ||
| "做", | ||
| "搭建", | ||
| "搭", | ||
| "构建", | ||
| "开发" | ||
| ]; | ||
| const SYSTEM_BUILD_TARGETS = [ | ||
| "系统", | ||
| "平台", | ||
| "管理系统", | ||
| "业务系统", | ||
| "crm", | ||
| "客户管理", | ||
| "项目管理", | ||
| "售后管理", | ||
| "审批系统" | ||
| ]; | ||
| const WORKFLOW_INTENT_KEYWORDS = [ | ||
| "工作流", | ||
| "workflow", | ||
| "flow", | ||
| "默认模型", | ||
| "ai 分析", | ||
| "审批流程", | ||
| "自动化" | ||
| ]; | ||
| const AUTH_INTENT_KEYWORDS = [ | ||
| "api-key", | ||
| "apikey", | ||
| "api key", | ||
| "api-secret", | ||
| "apisecret", | ||
| "api secret", | ||
| "token", | ||
| "登录", | ||
| "鉴权" | ||
| ]; | ||
| const TABLE_INTENT_KEYWORDS = [ | ||
| "多维表格", | ||
| "sheet", | ||
| "row", | ||
| "column", | ||
| "字段", | ||
| "视图", | ||
| "table" | ||
| ]; | ||
| const PERMISSION_INTENT_KEYWORDS = [ | ||
| "权限", | ||
| "行级权限", | ||
| "列权限", | ||
| "公开访问", | ||
| "只读", | ||
| "acl", | ||
| "协同越权" | ||
| ]; | ||
| const REPORT_INTENT_KEYWORDS = [ | ||
| "报表", | ||
| "图表", | ||
| "dashboard", | ||
| "参数筛选", | ||
| "数据源", | ||
| "统计", | ||
| "看板" | ||
| ]; | ||
| function getSystemOrchestratorBonus(skill, normalizedQuery) { | ||
| if (skill.name !== "dimens-system-orchestrator") return 0; | ||
| const hasBuildVerb = SYSTEM_BUILD_VERBS.some((keyword) => normalizedQuery.includes(keyword)); | ||
| const matchedTargets = SYSTEM_BUILD_TARGETS.filter((keyword) => normalizedQuery.includes(keyword)); | ||
| let score = 0; | ||
| if (hasBuildVerb && matchedTargets.length > 0) score += 10; | ||
| score += matchedTargets.length * 4; | ||
| return score; | ||
| } | ||
| function hasIntentKeyword(normalizedQuery, keywords) { | ||
| return keywords.some((keyword) => normalizedQuery.includes(keyword)); | ||
| } | ||
| function getSkillMatchSignals(skill, query) { | ||
| const normalizedQuery = query.toLowerCase(); | ||
| const haystacks = [ | ||
| skill.name, | ||
| skill.description, | ||
| ...skill.tags ?? [], | ||
| ...skill.commandGroups ?? [], | ||
| ...skill.commands ?? [], | ||
| ...skill.sdkModules ?? [], | ||
| ...skill.toolNames ?? [] | ||
| ].join("\n").toLowerCase(); | ||
| const compactQuery = normalizedQuery.replace(/\s+/g, ""); | ||
| const keywords = normalizedQuery.split(/\s+/).map((item) => item.trim()).filter(Boolean); | ||
| let keywordScore = 0; | ||
| const matchedBy = []; | ||
| keywords.forEach((keyword) => { | ||
| if (!keyword) return; | ||
| if (skill.name.toLowerCase().includes(keyword)) { | ||
| keywordScore += 4; | ||
| if (!matchedBy.includes("name-keyword")) matchedBy.push("name-keyword"); | ||
| return; | ||
| } | ||
| if (haystacks.includes(keyword)) { | ||
| keywordScore += 1; | ||
| if (!matchedBy.includes("context-keyword")) matchedBy.push("context-keyword"); | ||
| } | ||
| }); | ||
| let phraseScore = 0; | ||
| if (compactQuery && compactQuery !== normalizedQuery && haystacks.includes(compactQuery)) phraseScore += 2; | ||
| if (compactQuery && haystacks.includes(compactQuery)) phraseScore += 2; | ||
| if (phraseScore > 0 && !matchedBy.includes("compact-phrase")) matchedBy.push("compact-phrase"); | ||
| const systemBonus = getSystemOrchestratorBonus(skill, normalizedQuery); | ||
| if (systemBonus > 0) matchedBy.push("system-build-intent"); | ||
| if (skill.name === "dimens-workflow" && hasIntentKeyword(normalizedQuery, WORKFLOW_INTENT_KEYWORDS)) matchedBy.push("workflow-intent"); | ||
| if (skill.name === "dimens-key-auth" && hasIntentKeyword(normalizedQuery, AUTH_INTENT_KEYWORDS)) matchedBy.push("auth-intent"); | ||
| if (skill.name === "dimens-table" && hasIntentKeyword(normalizedQuery, TABLE_INTENT_KEYWORDS)) matchedBy.push("table-intent"); | ||
| if (skill.name === "dimens-permission" && hasIntentKeyword(normalizedQuery, PERMISSION_INTENT_KEYWORDS)) matchedBy.push("permission-intent"); | ||
| if (skill.name === "dimens-report" && hasIntentKeyword(normalizedQuery, REPORT_INTENT_KEYWORDS)) matchedBy.push("report-intent"); | ||
| const score = keywordScore + phraseScore + systemBonus; | ||
| const reasonParts = []; | ||
| if (systemBonus > 0) reasonParts.push("命中系统建设意图"); | ||
| if (matchedBy.includes("workflow-intent")) reasonParts.push("命中工作流意图"); | ||
| if (matchedBy.includes("auth-intent")) reasonParts.push("命中鉴权接入意图"); | ||
| if (matchedBy.includes("table-intent")) reasonParts.push("命中多维表格意图"); | ||
| if (matchedBy.includes("permission-intent")) reasonParts.push("命中权限意图"); | ||
| if (matchedBy.includes("report-intent")) reasonParts.push("命中报表意图"); | ||
| if (matchedBy.includes("name-keyword")) reasonParts.push("匹配到技能名关键词"); | ||
| if (matchedBy.includes("context-keyword")) reasonParts.push("匹配到描述或映射关键词"); | ||
| if (matchedBy.includes("compact-phrase")) reasonParts.push("匹配到紧凑短语"); | ||
| return { | ||
| score, | ||
| matchedBy, | ||
| reason: reasonParts.join(";") || "基于关键词相关性匹配" | ||
| }; | ||
| } | ||
| function registerSkillCommands() { | ||
| createCommandGroup("skill", "技能查看与提示语文档"); | ||
| registerGroupCommand("skill", createCommand("list", "列出所有已发现的技能", async (args) => { | ||
| const context = getContext(parseFlags(args)); | ||
| try { | ||
| const skills = getAllSkills(); | ||
| if (context.output === "json") { | ||
| console.log(formatSuccess("技能列表获取成功", skills.map((skill) => normalizeSkillForOutput(skill)), context.output)); | ||
| return; | ||
| } | ||
| console.log("\n已发现技能:\n"); | ||
| skills.forEach((skill) => { | ||
| console.log(`- ${skill.name}`); | ||
| console.log(` ${skill.description.split("\n")[0] ?? skill.description}`); | ||
| }); | ||
| console.log(""); | ||
| } catch (error) { | ||
| printError(context, error); | ||
| } | ||
| }, { | ||
| usage: "skill list", | ||
| examples: ["dimens-cli skill list"] | ||
| })); | ||
| registerGroupCommand("skill", createCommand("info", "查看技能元信息", async (args) => { | ||
| const context = getContext(parseFlags(args)); | ||
| try { | ||
| const skill = getSkillOrThrow(requireSkillName(args)); | ||
| const normalizedSkill = normalizeSkillForOutput(skill); | ||
| if (context.output === "json") { | ||
| console.log(formatSuccess("技能信息获取成功", normalizedSkill, context.output)); | ||
| return; | ||
| } | ||
| console.log(`\n技能: ${skill.name}`); | ||
| console.log(`描述: ${skill.description.split("\n")[0] ?? skill.description}`); | ||
| if (skill.skillPath) console.log(`主文件: ${toRelativeSkillPath(skill.skillPath)}`); | ||
| if (skill.referencesDir) console.log(`参考目录: ${toRelativeSkillPath(skill.referencesDir)}`); | ||
| printMapping(skill); | ||
| printList("推荐关键词示例", getRecommendExamples(skill.name)); | ||
| printList("references", skill.references?.map((reference) => toRelativeSkillPath(reference))); | ||
| console.log(""); | ||
| } catch (error) { | ||
| printError(context, error); | ||
| } | ||
| }, { | ||
| usage: "skill info <name>", | ||
| examples: ["dimens-cli skill info dimens-table"] | ||
| })); | ||
| registerGroupCommand("skill", createCommand("recommend", "根据文本或关键词推荐相关技能", async (args) => { | ||
| const context = getContext(parseFlags(args)); | ||
| try { | ||
| const query = getRecommendQuery(args); | ||
| if (!query) throw new Error("缺少推荐文本,请传入 skill recommend <text>"); | ||
| const rankedSkills = getAllSkills().map((skill) => ({ | ||
| skill, | ||
| ...getSkillMatchSignals(skill, query) | ||
| })).filter((item) => item.score > 0).sort((a, b) => b.score - a.score || a.skill.name.localeCompare(b.skill.name, "zh-CN")); | ||
| if (context.output === "json") { | ||
| console.log(formatSuccess("技能推荐完成", rankedSkills.map((item) => ({ | ||
| score: item.score, | ||
| matchedBy: item.matchedBy, | ||
| reason: item.reason, | ||
| skill: normalizeSkillForOutput(item.skill) | ||
| })), context.output)); | ||
| return; | ||
| } | ||
| console.log(`\n推荐 Skill(query: ${query}):\n`); | ||
| if (rankedSkills.length === 0) { | ||
| console.log("(无匹配结果)\n"); | ||
| return; | ||
| } | ||
| rankedSkills.forEach((item) => { | ||
| console.log(`- ${item.skill.name} (score: ${item.score})`); | ||
| console.log(` ${item.skill.description.split("\n")[0] ?? item.skill.description}`); | ||
| }); | ||
| console.log(""); | ||
| } catch (error) { | ||
| printError(context, error); | ||
| } | ||
| }, { | ||
| usage: "skill recommend <text>", | ||
| examples: ["dimens-cli skill recommend 工作流 默认模型 AI 分析", "dimens-cli skill recommend api-key token --output json"] | ||
| })); | ||
| registerGroupCommand("skill", createCommand("show", "显示技能文档内容", async (args) => { | ||
| const flags = parseFlags(args); | ||
| const context = getContext(flags); | ||
| try { | ||
| const skillName = requireSkillName(args.filter((arg) => !arg.startsWith("--"))); | ||
| const skill = getSkillOrThrow(skillName); | ||
| const normalizedSkill = normalizeSkillForOutput(skill); | ||
| if (!skill.skillPath) throw new Error(`技能 ${skillName} 缺少主文件路径`); | ||
| const mainOnly = flags["main-only"] === "true"; | ||
| const referencesOnly = flags["references-only"] === "true"; | ||
| const mappingOnly = flags["mapping-only"] === "true"; | ||
| const includeReferences = flags.references === "true" || referencesOnly; | ||
| if (context.output === "json") { | ||
| const payload = { skill: normalizedSkill }; | ||
| if (!referencesOnly && !mappingOnly) payload.main = readFileSync(skill.skillPath, "utf8"); | ||
| if (!mainOnly && !mappingOnly && skill.references && skill.references.length > 0) payload.references = skill.references.map((reference) => ({ | ||
| path: toRelativeSkillPath(reference), | ||
| content: readFileSync(reference, "utf8") | ||
| })); | ||
| if (!mainOnly && !referencesOnly) payload.mapping = { | ||
| commandGroups: skill.commandGroups ?? [], | ||
| commands: skill.commands ?? [], | ||
| sdkModules: skill.sdkModules ?? [], | ||
| toolNames: skill.toolNames ?? [] | ||
| }; | ||
| console.log(formatSuccess("技能文档获取成功", payload, context.output)); | ||
| return; | ||
| } | ||
| if (!referencesOnly && !mappingOnly) { | ||
| console.log(`\n===== ${skill.name} / ${toRelativeSkillPath(skill.skillPath)} =====\n`); | ||
| console.log(readFileSync(skill.skillPath, "utf8")); | ||
| } | ||
| if (!mainOnly && !referencesOnly) { | ||
| console.log(`\n===== ${skill.name} / mapping =====\n`); | ||
| printMapping(skill); | ||
| } | ||
| if (!mainOnly && !mappingOnly && includeReferences && skill.references && skill.references.length > 0) skill.references.forEach((reference) => { | ||
| console.log(`\n===== ${toRelativeSkillPath(reference)} =====\n`); | ||
| console.log(readFileSync(reference, "utf8")); | ||
| }); | ||
| console.log(""); | ||
| } catch (error) { | ||
| printError(context, error); | ||
| } | ||
| }, { | ||
| usage: "skill show <name> [--references] [--main-only] [--references-only] [--mapping-only]", | ||
| examples: [ | ||
| "dimens-cli skill show dimens-workflow", | ||
| "dimens-cli skill show dimens-workflow --references", | ||
| "dimens-cli skill show dimens-table --mapping-only", | ||
| "dimens-cli skill show dimens-key-auth --output json" | ||
| ] | ||
| })); | ||
| } | ||
| //#endregion | ||
| //#region src/commands/index.ts | ||
| var commands_exports = /* @__PURE__ */ __exportAll({ registerCommands: () => registerCommands }); | ||
| function registerCommands() { | ||
| logger.info("开始注册所有命令..."); | ||
| createCommandGroup("system", "系统命令"); | ||
| registerHelpCommand(); | ||
| registerVersionCommand(); | ||
| registerAuthCommands(); | ||
| registerSkillCommands(); | ||
| registerProjectCommands(); | ||
| registerSheetCommands(); | ||
| registerColumnCommands(); | ||
| registerRowCommands(); | ||
| registerAICommands(); | ||
| logger.info("所有命令注册完成"); | ||
| } | ||
| //#endregion | ||
| export { config as _, getRelatedSkillObjectsForExecutionContext as a, getAllSkills as c, clearCommands as d, getAllCommands as f, registerCommand as g, getGroupCommand as h, clearExecutionContext as i, getSkill as l, getCommandGroup as m, registerCommands as n, setExecutionContext as o, getCommand as p, parseFlags as r, SKILLS as s, commands_exports as t, getSkillsRootPath as u }; | ||
| //# sourceMappingURL=commands-CRE0o0GP.mjs.map |
Sorry, the diff of this file is too big to display
| import { t as __exportAll } from "./rolldown-runtime-95iHPtFO.mjs"; | ||
| import { a as AuthSDK, i as ColumnSDK, n as RowSDK, o as DimensClient, r as ProjectSDK, s as FlowChatSDK, t as SheetSDK } from "./sheet-DafechaB.mjs"; | ||
| //#region src/sdk/index.ts | ||
| var sdk_exports = /* @__PURE__ */ __exportAll({ | ||
| DimensSDK: () => DimensSDK, | ||
| createSDK: () => createSDK | ||
| }); | ||
| var DimensSDK = class { | ||
| client; | ||
| auth; | ||
| project; | ||
| sheet; | ||
| column; | ||
| row; | ||
| ai; | ||
| constructor(config) { | ||
| this.client = new DimensClient(config); | ||
| this.auth = new AuthSDK(this.client); | ||
| this.project = new ProjectSDK(this.client); | ||
| this.sheet = new SheetSDK(this.client); | ||
| this.column = new ColumnSDK(this.client); | ||
| this.row = new RowSDK(this.client); | ||
| this.ai = new FlowChatSDK(this.client); | ||
| } | ||
| }; | ||
| function createSDK(config) { | ||
| return new DimensSDK(config); | ||
| } | ||
| //#endregion | ||
| export { createSDK as n, sdk_exports as r, DimensSDK as t }; | ||
| //# sourceMappingURL=sdk-CTc2yzdu.mjs.map |
| {"version":3,"file":"sdk-CTc2yzdu.mjs","names":[],"sources":["../src/sdk/index.ts"],"sourcesContent":["import { AuthSDK } from './auth';\nimport { DimensClient, type APIResponse, type DimensClientOptions } from './client';\nimport { ColumnSDK } from './column';\nimport { FlowChatSDK } from './flow-chat';\nimport { ProjectSDK } from './project';\nimport { RowSDK } from './row';\nimport { SheetSDK } from './sheet';\n\nexport type { APIResponse, DimensClientOptions };\n\nexport interface SDKConfig extends DimensClientOptions {}\n\nexport class DimensSDK {\n readonly client: DimensClient;\n readonly auth: AuthSDK;\n readonly project: ProjectSDK;\n readonly sheet: SheetSDK;\n readonly column: ColumnSDK;\n readonly row: RowSDK;\n readonly ai: FlowChatSDK;\n\n constructor(config: SDKConfig) {\n this.client = new DimensClient(config);\n this.auth = new AuthSDK(this.client);\n this.project = new ProjectSDK(this.client);\n this.sheet = new SheetSDK(this.client);\n this.column = new ColumnSDK(this.client);\n this.row = new RowSDK(this.client);\n this.ai = new FlowChatSDK(this.client);\n }\n}\n\nexport function createSDK(config: SDKConfig): DimensSDK {\n return new DimensSDK(config);\n}\n\nexport { DimensClient } from './client';\nexport { AuthSDK } from './auth';\nexport { ProjectSDK } from './project';\nexport { SheetSDK } from './sheet';\nexport { ColumnSDK } from './column';\nexport { RowSDK } from './row';\nexport { FlowChatSDK } from './flow-chat';\n"],"mappings":";;;;;;;;AAYA,IAAa,YAAb,MAAuB;CACrB,AAAS;CACT,AAAS;CACT,AAAS;CACT,AAAS;CACT,AAAS;CACT,AAAS;CACT,AAAS;CAET,YAAY,QAAmB;AAC7B,OAAK,SAAS,IAAI,aAAa,OAAO;AACtC,OAAK,OAAO,IAAI,QAAQ,KAAK,OAAO;AACpC,OAAK,UAAU,IAAI,WAAW,KAAK,OAAO;AAC1C,OAAK,QAAQ,IAAI,SAAS,KAAK,OAAO;AACtC,OAAK,SAAS,IAAI,UAAU,KAAK,OAAO;AACxC,OAAK,MAAM,IAAI,OAAO,KAAK,OAAO;AAClC,OAAK,KAAK,IAAI,YAAY,KAAK,OAAO;;;AAI1C,SAAgB,UAAU,QAA8B;AACtD,QAAO,IAAI,UAAU,OAAO"} |
| import { dirname, join } from "path"; | ||
| import { readFileSync } from "fs"; | ||
| import { fileURLToPath } from "url"; | ||
| //#region src/core/version.ts | ||
| /** | ||
| * 版本信息 | ||
| */ | ||
| let _version; | ||
| function getVersion() { | ||
| if (_version) return _version; | ||
| try { | ||
| const packageJsonPath = join(dirname(fileURLToPath(import.meta.url)), "..", "..", "package.json"); | ||
| _version = JSON.parse(readFileSync(packageJsonPath, "utf-8")).version; | ||
| } catch { | ||
| _version = "1.0.0"; | ||
| } | ||
| return _version ?? "1.0.0"; | ||
| } | ||
| const version = getVersion(); | ||
| function getUserAgent() { | ||
| return `DimensCLI/${version} (Node.js/${process.version})`; | ||
| } | ||
| //#endregion | ||
| //#region src/sdk/flow-chat.ts | ||
| var FlowChatSDK = class { | ||
| constructor(client) { | ||
| this.client = client; | ||
| } | ||
| completions(teamId, payload) { | ||
| return this.client.post(`/app/flow/${teamId}/v1/chat/completions`, payload); | ||
| } | ||
| }; | ||
| //#endregion | ||
| //#region src/core/http.ts | ||
| async function requestJson(url, init = {}) { | ||
| const response = await fetch(url, init); | ||
| const payload = await response.json(); | ||
| if (!response.ok) throw new Error(payload?.message || `HTTP ${response.status}`); | ||
| return payload; | ||
| } | ||
| //#endregion | ||
| //#region src/sdk/client.ts | ||
| var DimensClient = class { | ||
| options; | ||
| constructor(options) { | ||
| this.options = options; | ||
| } | ||
| getOptions() { | ||
| return { ...this.options }; | ||
| } | ||
| async get(path, query, init = {}) { | ||
| return requestJson(this.buildUrl(path, query), { | ||
| ...init, | ||
| method: "GET", | ||
| headers: this.buildHeaders(init.headers) | ||
| }); | ||
| } | ||
| async post(path, body, init = {}) { | ||
| const requestInit = { | ||
| ...init, | ||
| method: "POST", | ||
| headers: this.buildHeaders(init.headers, true) | ||
| }; | ||
| if (body !== void 0) requestInit.body = JSON.stringify(body); | ||
| return requestJson(this.buildUrl(path), requestInit); | ||
| } | ||
| buildUrl(path, query) { | ||
| const base = this.options.baseUrl.replace(/\/+$/, ""); | ||
| const normalizedPath = path.startsWith("/") ? path : `/${path}`; | ||
| const url = new URL(`${base}${normalizedPath}`); | ||
| Object.entries(query || {}).forEach(([key, value]) => { | ||
| if (value === void 0 || value === null || value === "") return; | ||
| url.searchParams.set(key, String(value)); | ||
| }); | ||
| return url.toString(); | ||
| } | ||
| buildHeaders(headers, hasJsonBody = false) { | ||
| const merged = normalizeHeaders(headers); | ||
| merged.Accept = "application/json"; | ||
| merged["User-Agent"] = getUserAgent(); | ||
| if (hasJsonBody) merged["Content-Type"] = "application/json"; | ||
| if (this.options.token) merged.Authorization = `Bearer ${this.options.token}`; | ||
| if (this.options.refreshToken) merged["X-Refresh-Token"] = this.options.refreshToken; | ||
| return merged; | ||
| } | ||
| }; | ||
| function normalizeHeaders(headers) { | ||
| if (!headers) return {}; | ||
| if (typeof Headers !== "undefined" && headers instanceof Headers) return Object.fromEntries(headers.entries()); | ||
| if (Array.isArray(headers)) return Object.fromEntries(headers.map(([key, value]) => [String(key), String(value)])); | ||
| const normalized = {}; | ||
| Object.entries(headers).forEach(([key, value]) => { | ||
| normalized[key] = typeof value === "string" ? value : value.join(", "); | ||
| }); | ||
| return normalized; | ||
| } | ||
| //#endregion | ||
| //#region src/sdk/auth.ts | ||
| var AuthSDK = class { | ||
| constructor(client) { | ||
| this.client = client; | ||
| } | ||
| login(payload) { | ||
| return this.client.post("/login", payload); | ||
| } | ||
| loginByApiKey(payload) { | ||
| return this.client.post("/open/user/login/apiKey", payload); | ||
| } | ||
| exchangeTokenByApiKey(payload) { | ||
| return this.loginByApiKey(payload); | ||
| } | ||
| refreshToken() { | ||
| return this.client.get("/refreshToken"); | ||
| } | ||
| }; | ||
| //#endregion | ||
| //#region src/sdk/column.ts | ||
| var ColumnSDK = class { | ||
| constructor(client) { | ||
| this.client = client; | ||
| } | ||
| list(teamId, projectId, sheetId) { | ||
| return this.client.get(`/app/mul/${teamId}/${projectId}/sheet/${sheetId}/column/list`); | ||
| } | ||
| create(teamId, projectId, sheetId, payload) { | ||
| return this.client.post(`/app/mul/${teamId}/${projectId}/sheet/${sheetId}/column/create`, payload); | ||
| } | ||
| update(sheetId, fieldId, payload) { | ||
| return this.client.post(`/app/mul/sheet/${sheetId}/column/${fieldId}/update`, payload); | ||
| } | ||
| delete(sheetId, fieldId) { | ||
| return this.client.post(`/app/mul/sheet/${sheetId}/column/${fieldId}/delete`); | ||
| } | ||
| }; | ||
| //#endregion | ||
| //#region src/sdk/project.ts | ||
| var ProjectSDK = class { | ||
| constructor(client) { | ||
| this.client = client; | ||
| } | ||
| page(teamId, payload) { | ||
| return this.client.post(`/app/org/${teamId}/project/page`, payload); | ||
| } | ||
| info(teamId, id) { | ||
| return this.client.get(`/app/org/${teamId}/project/info`, { id }); | ||
| } | ||
| create(teamId, payload) { | ||
| return this.client.post(`/app/org/${teamId}/project/add`, payload); | ||
| } | ||
| update(teamId, payload) { | ||
| return this.client.post(`/app/org/${teamId}/project/update`, payload); | ||
| } | ||
| trash(teamId, ids) { | ||
| return this.client.post(`/app/org/${teamId}/project/trash`, { ids }); | ||
| } | ||
| restore(teamId, ids) { | ||
| return this.client.post(`/app/org/${teamId}/project/restore`, { ids }); | ||
| } | ||
| }; | ||
| //#endregion | ||
| //#region src/sdk/row.ts | ||
| var RowSDK = class { | ||
| constructor(client) { | ||
| this.client = client; | ||
| } | ||
| page(teamId, projectId, sheetId, payload) { | ||
| return this.client.post(`/app/mul/${teamId}/${projectId}/sheet/${sheetId}/row/page`, payload); | ||
| } | ||
| info(teamId, projectId, sheetId, rowId) { | ||
| return this.client.get(`/app/mul/${teamId}/${projectId}/sheet/${sheetId}/row/${rowId}/info`); | ||
| } | ||
| create(sheetId, payload) { | ||
| return this.client.post(`/app/mul/sheet/${sheetId}/row/create`, payload); | ||
| } | ||
| update(sheetId, rowId, values, version) { | ||
| return this.client.post(`/app/mul/sheet/${sheetId}/row/${rowId}/update`, { | ||
| values, | ||
| version | ||
| }); | ||
| } | ||
| delete(sheetId, rowId) { | ||
| return this.client.post(`/app/mul/sheet/${sheetId}/row/${rowId}/delete`); | ||
| } | ||
| updateCell(sheetId, payload) { | ||
| return this.client.post(`/app/mul/sheet/${sheetId}/row/cell`, payload); | ||
| } | ||
| }; | ||
| //#endregion | ||
| //#region src/sdk/sheet.ts | ||
| var SheetSDK = class { | ||
| constructor(client) { | ||
| this.client = client; | ||
| } | ||
| list(projectId) { | ||
| return this.client.get(`/app/mul/project/${projectId}/sheet/list`); | ||
| } | ||
| tree(projectId) { | ||
| return this.client.get(`/app/mul/project/${projectId}/sheet/tree`); | ||
| } | ||
| create(projectId, payload) { | ||
| return this.client.post(`/app/mul/project/${projectId}/sheet/create`, payload); | ||
| } | ||
| info(teamId, projectId, sheetId) { | ||
| return this.client.get(`/app/mul/${teamId}/${projectId}/sheet/${sheetId}/info`); | ||
| } | ||
| update(teamId, projectId, sheetId, payload) { | ||
| return this.client.post(`/app/mul/${teamId}/${projectId}/sheet/${sheetId}/update`, payload); | ||
| } | ||
| delete(teamId, projectId, sheetId) { | ||
| return this.client.post(`/app/mul/${teamId}/${projectId}/sheet/${sheetId}/delete`); | ||
| } | ||
| structure(sheetId) { | ||
| return this.client.get(`/app/mul/sheet/${sheetId}/structure`); | ||
| } | ||
| }; | ||
| //#endregion | ||
| export { AuthSDK as a, getUserAgent as c, ColumnSDK as i, getVersion as l, RowSDK as n, DimensClient as o, ProjectSDK as r, FlowChatSDK as s, SheetSDK as t, version as u }; | ||
| //# sourceMappingURL=sheet-DafechaB.mjs.map |
| {"version":3,"file":"sheet-DafechaB.mjs","names":[],"sources":["../src/core/version.ts","../src/sdk/flow-chat.ts","../src/core/http.ts","../src/sdk/client.ts","../src/sdk/auth.ts","../src/sdk/column.ts","../src/sdk/project.ts","../src/sdk/row.ts","../src/sdk/sheet.ts"],"sourcesContent":["/**\n * 版本信息\n */\n\nimport { readFileSync } from 'fs';\nimport { join } from 'path';\nimport { fileURLToPath } from 'url';\nimport { dirname } from 'path';\n\nlet _version: string | undefined;\n\nexport function getVersion(): string {\n if (_version) return _version;\n\n try {\n const __filename = fileURLToPath(import.meta.url);\n const __dirname = dirname(__filename);\n const packageJsonPath = join(__dirname, '..', '..', 'package.json');\n const packageJson = JSON.parse(readFileSync(packageJsonPath, 'utf-8'));\n _version = packageJson.version;\n } catch {\n _version = '1.0.0';\n }\n\n return _version ?? '1.0.0';\n}\n\nexport const version = getVersion();\n\nexport function getUserAgent(): string {\n return `DimensCLI/${version} (Node.js/${process.version})`;\n}\n","import type { APIResponse } from './client';\nimport { DimensClient } from './client';\n\nexport interface FlowChatMessage {\n role: 'system' | 'user' | 'assistant';\n content: string;\n}\n\nexport interface FlowChatCompletionsPayload {\n model?: string | number;\n messages: FlowChatMessage[];\n stream?: boolean;\n user?: string;\n sessionId?: string;\n [key: string]: unknown;\n}\n\nexport interface FlowChatCompletionChoice {\n index?: number;\n message: {\n role: string;\n content: string;\n };\n finish_reason?: string | null;\n}\n\nexport interface FlowChatCompletionResult {\n id: string;\n object?: string;\n created?: number;\n model?: string;\n choices: FlowChatCompletionChoice[];\n usage?: Record<string, unknown>;\n}\n\nexport class FlowChatSDK {\n constructor(private readonly client: DimensClient) {}\n\n completions(\n teamId: string,\n payload: FlowChatCompletionsPayload\n ): Promise<APIResponse<FlowChatCompletionResult>> {\n return this.client.post<FlowChatCompletionResult>(\n `/app/flow/${teamId}/v1/chat/completions`,\n payload\n );\n }\n}\n","export async function requestJson<T>(\n url: string,\n init: RequestInit = {}\n): Promise<T> {\n const response = await fetch(url, init);\n const payload = (await response.json()) as { message?: string };\n\n if (!response.ok) {\n throw new Error(payload?.message || `HTTP ${response.status}`);\n }\n\n return payload as T;\n}\n","import { getUserAgent } from '../core/version';\nimport { requestJson } from '../core/http';\n\nexport interface DimensClientOptions {\n baseUrl: string;\n token?: string;\n refreshToken?: string;\n teamId?: string;\n projectId?: string;\n}\n\nexport interface APIResponse<T> {\n code: number;\n message: string;\n data: T;\n}\n\ntype QueryValue = string | number | boolean | null | undefined;\ntype QueryParams = Record<string, QueryValue>;\ntype HeaderTupleList = Array<[string, string]> | string[][];\ntype HeaderObjectInput = Record<string, string | readonly string[]>;\n\nexport class DimensClient {\n private readonly options: DimensClientOptions;\n\n constructor(options: DimensClientOptions) {\n this.options = options;\n }\n\n getOptions(): DimensClientOptions {\n return { ...this.options };\n }\n\n async get<T>(\n path: string,\n query?: QueryParams,\n init: RequestInit = {}\n ): Promise<APIResponse<T>> {\n return requestJson<APIResponse<T>>(this.buildUrl(path, query), {\n ...init,\n method: 'GET',\n headers: this.buildHeaders(init.headers),\n });\n }\n\n async post<T>(\n path: string,\n body?: unknown,\n init: RequestInit = {}\n ): Promise<APIResponse<T>> {\n const requestInit: RequestInit = {\n ...init,\n method: 'POST',\n headers: this.buildHeaders(init.headers, true),\n };\n\n if (body !== undefined) {\n requestInit.body = JSON.stringify(body);\n }\n\n return requestJson<APIResponse<T>>(this.buildUrl(path), requestInit);\n }\n\n private buildUrl(path: string, query?: QueryParams): string {\n const base = this.options.baseUrl.replace(/\\/+$/, '');\n const normalizedPath = path.startsWith('/') ? path : `/${path}`;\n const url = new URL(`${base}${normalizedPath}`);\n\n Object.entries(query || {}).forEach(([key, value]) => {\n if (value === undefined || value === null || value === '') {\n return;\n }\n url.searchParams.set(key, String(value));\n });\n\n return url.toString();\n }\n\n private buildHeaders(\n headers?: unknown,\n hasJsonBody = false\n ): Record<string, string> {\n const merged = normalizeHeaders(headers);\n merged.Accept = 'application/json';\n merged['User-Agent'] = getUserAgent();\n\n if (hasJsonBody) {\n merged['Content-Type'] = 'application/json';\n }\n if (this.options.token) {\n merged.Authorization = `Bearer ${this.options.token}`;\n }\n if (this.options.refreshToken) {\n merged['X-Refresh-Token'] = this.options.refreshToken;\n }\n\n return merged;\n }\n}\n\nfunction normalizeHeaders(headers?: unknown): Record<string, string> {\n if (!headers) {\n return {};\n }\n if (typeof Headers !== 'undefined' && headers instanceof Headers) {\n return Object.fromEntries(headers.entries());\n }\n if (Array.isArray(headers)) {\n return Object.fromEntries(\n (headers as HeaderTupleList).map(([key, value]) => [String(key), String(value)])\n );\n }\n const normalized: Record<string, string> = {};\n Object.entries(headers as HeaderObjectInput).forEach(([key, value]) => {\n normalized[key] = typeof value === 'string' ? value : value.join(', ');\n });\n return normalized;\n}\n","import type { APIResponse } from './client';\nimport { DimensClient } from './client';\n\nexport interface LoginPayload {\n username: string;\n password: string;\n captchaId?: string;\n verifyCode?: string;\n}\n\nexport interface ApiKeyLoginPayload {\n apiKey: string;\n apiSecret: string;\n}\n\nexport interface LoginResult {\n token: string;\n refreshToken?: string;\n expire?: number;\n userInfo?: Record<string, unknown>;\n}\n\nexport interface RefreshTokenResult {\n token: string;\n refreshToken?: string;\n expire?: number;\n}\n\nexport class AuthSDK {\n constructor(private readonly client: DimensClient) {}\n\n login(payload: LoginPayload): Promise<APIResponse<LoginResult>> {\n return this.client.post<LoginResult>('/login', payload);\n }\n\n loginByApiKey(payload: ApiKeyLoginPayload): Promise<APIResponse<LoginResult>> {\n return this.client.post<LoginResult>('/open/user/login/apiKey', payload);\n }\n\n exchangeTokenByApiKey(\n payload: ApiKeyLoginPayload\n ): Promise<APIResponse<LoginResult>> {\n return this.loginByApiKey(payload);\n }\n\n refreshToken(): Promise<APIResponse<RefreshTokenResult>> {\n return this.client.get<RefreshTokenResult>('/refreshToken');\n }\n}\n","import type { APIResponse } from './client';\nimport { DimensClient } from './client';\n\nexport interface ColumnInfo {\n id: string;\n title?: string;\n type?: string;\n [key: string]: unknown;\n}\n\nexport interface ColumnMutationPayload {\n title?: string;\n type?: string;\n description?: string;\n [key: string]: unknown;\n}\n\nexport class ColumnSDK {\n constructor(private readonly client: DimensClient) {}\n\n list(\n teamId: string,\n projectId: string,\n sheetId: string\n ): Promise<APIResponse<ColumnInfo[]>> {\n return this.client.get<ColumnInfo[]>(\n `/app/mul/${teamId}/${projectId}/sheet/${sheetId}/column/list`\n );\n }\n\n create(\n teamId: string,\n projectId: string,\n sheetId: string,\n payload: ColumnMutationPayload\n ): Promise<APIResponse<ColumnInfo>> {\n return this.client.post<ColumnInfo>(\n `/app/mul/${teamId}/${projectId}/sheet/${sheetId}/column/create`,\n payload\n );\n }\n\n update(\n sheetId: string,\n fieldId: string,\n payload: ColumnMutationPayload\n ): Promise<APIResponse<ColumnInfo>> {\n return this.client.post<ColumnInfo>(\n `/app/mul/sheet/${sheetId}/column/${fieldId}/update`,\n payload\n );\n }\n\n delete(sheetId: string, fieldId: string): Promise<APIResponse<boolean>> {\n return this.client.post<boolean>(`/app/mul/sheet/${sheetId}/column/${fieldId}/delete`);\n }\n}\n","import type { APIResponse } from './client';\nimport { DimensClient } from './client';\n\nexport interface ProjectInfo {\n id: string;\n name: string;\n [key: string]: unknown;\n}\n\nexport interface ProjectPagePayload {\n page?: number;\n size?: number;\n keyword?: string;\n [key: string]: unknown;\n}\n\nexport interface ProjectPageResult {\n list: ProjectInfo[];\n pagination?: Record<string, unknown>;\n [key: string]: unknown;\n}\n\nexport interface ProjectMutationPayload {\n id?: string;\n name?: string;\n icon?: string;\n remark?: string;\n [key: string]: unknown;\n}\n\nexport class ProjectSDK {\n constructor(private readonly client: DimensClient) {}\n\n page(teamId: string, payload: ProjectPagePayload): Promise<APIResponse<ProjectPageResult>> {\n return this.client.post<ProjectPageResult>(`/app/org/${teamId}/project/page`, payload);\n }\n\n info(teamId: string, id: string): Promise<APIResponse<ProjectInfo>> {\n return this.client.get<ProjectInfo>(`/app/org/${teamId}/project/info`, { id });\n }\n\n create(\n teamId: string,\n payload: ProjectMutationPayload\n ): Promise<APIResponse<ProjectInfo>> {\n return this.client.post<ProjectInfo>(`/app/org/${teamId}/project/add`, payload);\n }\n\n update(\n teamId: string,\n payload: ProjectMutationPayload\n ): Promise<APIResponse<ProjectInfo>> {\n return this.client.post<ProjectInfo>(`/app/org/${teamId}/project/update`, payload);\n }\n\n trash(teamId: string, ids: string[]): Promise<APIResponse<boolean>> {\n return this.client.post<boolean>(`/app/org/${teamId}/project/trash`, { ids });\n }\n\n restore(teamId: string, ids: string[]): Promise<APIResponse<boolean>> {\n return this.client.post<boolean>(`/app/org/${teamId}/project/restore`, { ids });\n }\n}\n","import type { APIResponse } from './client';\nimport { DimensClient } from './client';\n\nexport interface RowInfo {\n id: string;\n [key: string]: unknown;\n}\n\nexport interface RowPagePayload {\n page?: number;\n size?: number;\n viewId?: string;\n filters?: unknown[];\n sorter?: unknown;\n [key: string]: unknown;\n}\n\nexport interface RowPageResult {\n list: RowInfo[];\n total?: number;\n [key: string]: unknown;\n}\n\nexport interface RowCreatePayload {\n values?: Record<string, unknown>;\n [key: string]: unknown;\n}\n\nexport interface RowCellPayload {\n rowId: string;\n columnId: string;\n value: unknown;\n [key: string]: unknown;\n}\n\nexport class RowSDK {\n constructor(private readonly client: DimensClient) {}\n\n page(\n teamId: string,\n projectId: string,\n sheetId: string,\n payload: RowPagePayload\n ): Promise<APIResponse<RowPageResult>> {\n return this.client.post<RowPageResult>(\n `/app/mul/${teamId}/${projectId}/sheet/${sheetId}/row/page`,\n payload\n );\n }\n\n info(\n teamId: string,\n projectId: string,\n sheetId: string,\n rowId: string\n ): Promise<APIResponse<RowInfo>> {\n return this.client.get<RowInfo>(\n `/app/mul/${teamId}/${projectId}/sheet/${sheetId}/row/${rowId}/info`\n );\n }\n\n create(sheetId: string, payload: RowCreatePayload): Promise<APIResponse<RowInfo>> {\n return this.client.post<RowInfo>(`/app/mul/sheet/${sheetId}/row/create`, payload);\n }\n\n update(\n sheetId: string,\n rowId: string,\n values: Record<string, unknown>,\n version: number\n ): Promise<APIResponse<RowInfo>> {\n return this.client.post<RowInfo>(`/app/mul/sheet/${sheetId}/row/${rowId}/update`, {\n values,\n version,\n });\n }\n\n delete(sheetId: string, rowId: string): Promise<APIResponse<boolean>> {\n return this.client.post<boolean>(`/app/mul/sheet/${sheetId}/row/${rowId}/delete`);\n }\n\n updateCell(sheetId: string, payload: RowCellPayload): Promise<APIResponse<boolean>> {\n return this.client.post<boolean>(`/app/mul/sheet/${sheetId}/row/cell`, payload);\n }\n}\n","import type { APIResponse } from './client';\nimport { DimensClient } from './client';\n\nexport interface SheetInfo {\n id: string;\n name?: string;\n [key: string]: unknown;\n}\n\nexport interface SheetMutationPayload {\n name?: string;\n icon?: string;\n folderId?: string;\n [key: string]: unknown;\n}\n\nexport class SheetSDK {\n constructor(private readonly client: DimensClient) {}\n\n list(projectId: string): Promise<APIResponse<SheetInfo[]>> {\n return this.client.get<SheetInfo[]>(`/app/mul/project/${projectId}/sheet/list`);\n }\n\n tree(projectId: string): Promise<APIResponse<unknown[]>> {\n return this.client.get<unknown[]>(`/app/mul/project/${projectId}/sheet/tree`);\n }\n\n create(projectId: string, payload: SheetMutationPayload): Promise<APIResponse<SheetInfo>> {\n return this.client.post<SheetInfo>(`/app/mul/project/${projectId}/sheet/create`, payload);\n }\n\n info(teamId: string, projectId: string, sheetId: string): Promise<APIResponse<SheetInfo>> {\n return this.client.get<SheetInfo>(\n `/app/mul/${teamId}/${projectId}/sheet/${sheetId}/info`\n );\n }\n\n update(\n teamId: string,\n projectId: string,\n sheetId: string,\n payload: SheetMutationPayload\n ): Promise<APIResponse<SheetInfo>> {\n return this.client.post<SheetInfo>(\n `/app/mul/${teamId}/${projectId}/sheet/${sheetId}/update`,\n payload\n );\n }\n\n delete(teamId: string, projectId: string, sheetId: string): Promise<APIResponse<boolean>> {\n return this.client.post<boolean>(\n `/app/mul/${teamId}/${projectId}/sheet/${sheetId}/delete`\n );\n }\n\n structure(sheetId: string): Promise<APIResponse<Record<string, unknown>>> {\n return this.client.get<Record<string, unknown>>(`/app/mul/sheet/${sheetId}/structure`);\n }\n}\n"],"mappings":"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"} |
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
452994
0.28%59
1.72%2111
0.14%397
0.51%