prompt-plus 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +118 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +49 -0
- package/dist/commands.d.ts +14 -0
- package/dist/commands.js +299 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +5 -0
- package/dist/templates/index.d.ts +2 -0
- package/dist/templates/index.js +92 -0
- package/dist/types.d.ts +17 -0
- package/dist/types.js +2 -0
- package/package.json +51 -0
package/README.md
ADDED
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
# prompt-plus
|
|
2
|
+
|
|
3
|
+
AI 提示词模板管理工具 - 生成符合项目规范的提示词
|
|
4
|
+
|
|
5
|
+
## 安装
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install -g prompt-plus
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## 快速开始
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
# 1. 添加官方模板仓库
|
|
15
|
+
prompt-plus repo add official https://github.com/LeeSeaside/prompt-plus-templates.git
|
|
16
|
+
|
|
17
|
+
# 2. 同步模板
|
|
18
|
+
prompt-plus repo sync
|
|
19
|
+
|
|
20
|
+
# 3. 查看可用模板
|
|
21
|
+
prompt-plus list
|
|
22
|
+
|
|
23
|
+
# 4. 使用模板
|
|
24
|
+
prompt-plus use backend-api
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
## 命令
|
|
28
|
+
|
|
29
|
+
### 模板操作
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
# 列出所有模板
|
|
33
|
+
prompt-plus list
|
|
34
|
+
prompt-plus ls
|
|
35
|
+
|
|
36
|
+
# 使用模板(交互式选择)
|
|
37
|
+
prompt-plus use
|
|
38
|
+
|
|
39
|
+
# 使用指定模板
|
|
40
|
+
prompt-plus use <模板名>
|
|
41
|
+
|
|
42
|
+
# 指定输出目录
|
|
43
|
+
prompt-plus use <模板名> -o ./my-prompts
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
### 仓库管理
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
# 查看仓库列表
|
|
50
|
+
prompt-plus repo ls
|
|
51
|
+
|
|
52
|
+
# 添加仓库
|
|
53
|
+
prompt-plus repo add <名称> <Git地址>
|
|
54
|
+
prompt-plus repo add official https://github.com/LeeSeaside/prompt-plus-templates.git
|
|
55
|
+
|
|
56
|
+
# 添加私有仓库(指定分支)
|
|
57
|
+
prompt-plus repo add company git@github.com:company/prompts.git -b develop
|
|
58
|
+
|
|
59
|
+
# 同步仓库
|
|
60
|
+
prompt-plus repo sync # 同步所有
|
|
61
|
+
prompt-plus repo sync official # 同步指定仓库
|
|
62
|
+
|
|
63
|
+
# 移除仓库
|
|
64
|
+
prompt-plus repo rm <名称>
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
## 自建模板仓库
|
|
68
|
+
|
|
69
|
+
创建 Git 仓库,在 `templates/` 目录下放置 Markdown 模板文件:
|
|
70
|
+
|
|
71
|
+
```
|
|
72
|
+
my-templates/
|
|
73
|
+
└── templates/
|
|
74
|
+
├── my-template-1.md
|
|
75
|
+
└── my-template-2.md
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
模板格式(Markdown + Front Matter):
|
|
79
|
+
|
|
80
|
+
```markdown
|
|
81
|
+
---
|
|
82
|
+
name: my-template
|
|
83
|
+
description: 模板描述
|
|
84
|
+
category: backend
|
|
85
|
+
outputFileName: my-template-prompt.md
|
|
86
|
+
---
|
|
87
|
+
|
|
88
|
+
# 模板标题
|
|
89
|
+
|
|
90
|
+
## 任务
|
|
91
|
+
模板内容...
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
## 工作流程
|
|
95
|
+
|
|
96
|
+
```
|
|
97
|
+
模板 → 正式提示词 → 对接文档/代码
|
|
98
|
+
|
|
99
|
+
.prompts/
|
|
100
|
+
├── templates/ # 提示词模板
|
|
101
|
+
└── generated/ # 正式提示词(AI 生成)
|
|
102
|
+
|
|
103
|
+
docs/
|
|
104
|
+
└── api/ # 对接文档(业务相关)
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
## 本地开发
|
|
108
|
+
|
|
109
|
+
```bash
|
|
110
|
+
npm install
|
|
111
|
+
npm run build
|
|
112
|
+
npm link
|
|
113
|
+
prompt-plus list
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
## License
|
|
117
|
+
|
|
118
|
+
MIT
|
package/dist/cli.d.ts
ADDED
package/dist/cli.js
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
const commander_1 = require("commander");
|
|
5
|
+
const commands_1 = require("./commands");
|
|
6
|
+
const program = new commander_1.Command();
|
|
7
|
+
program
|
|
8
|
+
.name('prompt-plus')
|
|
9
|
+
.description('AI提示词模板管理工具 - 生成符合项目规范的提示词')
|
|
10
|
+
.version('1.0.0');
|
|
11
|
+
program
|
|
12
|
+
.command('list')
|
|
13
|
+
.alias('ls')
|
|
14
|
+
.description('列出所有可用的提示词模板')
|
|
15
|
+
.option('-r, --repo <name>', '指定仓库名称')
|
|
16
|
+
.action(commands_1.listTemplates);
|
|
17
|
+
program
|
|
18
|
+
.command('use [templateName]')
|
|
19
|
+
.description('选择并使用模板生成提示词')
|
|
20
|
+
.option('-o, --output <path>', '输出路径', '.prompts')
|
|
21
|
+
.option('-r, --repo <name>', '指定仓库名称')
|
|
22
|
+
.action(commands_1.useTemplate);
|
|
23
|
+
program
|
|
24
|
+
.command('init')
|
|
25
|
+
.description('初始化配置文件')
|
|
26
|
+
.action(commands_1.initConfig);
|
|
27
|
+
program
|
|
28
|
+
.command('repo')
|
|
29
|
+
.description('管理模板仓库')
|
|
30
|
+
.addCommand(new commander_1.Command('add')
|
|
31
|
+
.description('添加模板仓库')
|
|
32
|
+
.argument('<name>', '仓库名称')
|
|
33
|
+
.argument('<url>', '仓库地址')
|
|
34
|
+
.option('-b, --branch <branch>', '分支名称', 'main')
|
|
35
|
+
.action(commands_1.addRepo))
|
|
36
|
+
.addCommand(new commander_1.Command('remove')
|
|
37
|
+
.alias('rm')
|
|
38
|
+
.description('移除模板仓库')
|
|
39
|
+
.argument('<name>', '仓库名称')
|
|
40
|
+
.action(commands_1.removeRepo))
|
|
41
|
+
.addCommand(new commander_1.Command('list')
|
|
42
|
+
.alias('ls')
|
|
43
|
+
.description('列出所有模板仓库')
|
|
44
|
+
.action(commands_1.listRepos))
|
|
45
|
+
.addCommand(new commander_1.Command('sync')
|
|
46
|
+
.description('同步模板仓库')
|
|
47
|
+
.argument('[name]', '仓库名称(不指定则同步所有)')
|
|
48
|
+
.action(commands_1.syncRepo));
|
|
49
|
+
program.parse();
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export declare function listTemplates(options?: {
|
|
2
|
+
repo?: string;
|
|
3
|
+
}): Promise<void>;
|
|
4
|
+
export declare function useTemplate(templateName?: string, options?: {
|
|
5
|
+
output?: string;
|
|
6
|
+
repo?: string;
|
|
7
|
+
}): Promise<void>;
|
|
8
|
+
export declare function initConfig(): Promise<void>;
|
|
9
|
+
export declare function addRepo(name: string, url: string, options?: {
|
|
10
|
+
branch?: string;
|
|
11
|
+
}): Promise<void>;
|
|
12
|
+
export declare function removeRepo(name: string): Promise<void>;
|
|
13
|
+
export declare function listRepos(): Promise<void>;
|
|
14
|
+
export declare function syncRepo(name?: string): Promise<void>;
|
package/dist/commands.js
ADDED
|
@@ -0,0 +1,299 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.listTemplates = listTemplates;
|
|
37
|
+
exports.useTemplate = useTemplate;
|
|
38
|
+
exports.initConfig = initConfig;
|
|
39
|
+
exports.addRepo = addRepo;
|
|
40
|
+
exports.removeRepo = removeRepo;
|
|
41
|
+
exports.listRepos = listRepos;
|
|
42
|
+
exports.syncRepo = syncRepo;
|
|
43
|
+
const fs = __importStar(require("fs"));
|
|
44
|
+
const path = __importStar(require("path"));
|
|
45
|
+
const child_process_1 = require("child_process");
|
|
46
|
+
const templates_1 = require("./templates");
|
|
47
|
+
// 配置文件路径(全局配置)
|
|
48
|
+
const getGlobalConfigDir = () => path.join(process.env.HOME || process.env.USERPROFILE || '', '.prompt-plus');
|
|
49
|
+
const getGlobalConfigPath = () => path.join(getGlobalConfigDir(), 'config.json');
|
|
50
|
+
const getReposDir = () => path.join(getGlobalConfigDir(), 'repos');
|
|
51
|
+
// 动态导入 ESM 模块
|
|
52
|
+
async function getChalk() {
|
|
53
|
+
return (await Promise.resolve().then(() => __importStar(require('chalk')))).default;
|
|
54
|
+
}
|
|
55
|
+
async function getInquirer() {
|
|
56
|
+
return (await Promise.resolve().then(() => __importStar(require('inquirer')))).default;
|
|
57
|
+
}
|
|
58
|
+
// 获取全局配置
|
|
59
|
+
function getConfig() {
|
|
60
|
+
const configPath = getGlobalConfigPath();
|
|
61
|
+
if (fs.existsSync(configPath)) {
|
|
62
|
+
return JSON.parse(fs.readFileSync(configPath, 'utf-8'));
|
|
63
|
+
}
|
|
64
|
+
return {
|
|
65
|
+
defaultRepo: '',
|
|
66
|
+
repos: [],
|
|
67
|
+
outputDir: '.prompts',
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
// 保存全局配置
|
|
71
|
+
function saveConfig(config) {
|
|
72
|
+
const configDir = getGlobalConfigDir();
|
|
73
|
+
if (!fs.existsSync(configDir)) {
|
|
74
|
+
fs.mkdirSync(configDir, { recursive: true });
|
|
75
|
+
}
|
|
76
|
+
fs.writeFileSync(getGlobalConfigPath(), JSON.stringify(config, null, 2), 'utf-8');
|
|
77
|
+
}
|
|
78
|
+
// 获取所有模板(按仓库分组)
|
|
79
|
+
async function getAllTemplatesWithRepo(repoName) {
|
|
80
|
+
const config = getConfig();
|
|
81
|
+
const templates = [];
|
|
82
|
+
// 指定了具体仓库
|
|
83
|
+
if (repoName) {
|
|
84
|
+
const repo = config.repos.find((r) => r.name === repoName);
|
|
85
|
+
if (repo) {
|
|
86
|
+
const repoDir = path.join(getReposDir(), repo.name);
|
|
87
|
+
if (fs.existsSync(repoDir)) {
|
|
88
|
+
const repoTemplates = (0, templates_1.loadTemplatesFromDir)(path.join(repoDir, 'templates'));
|
|
89
|
+
return repoTemplates.map((t) => ({ ...t, repoName: repo.name }));
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
return [];
|
|
93
|
+
}
|
|
94
|
+
// 未指定仓库:合并所有已同步仓库模板
|
|
95
|
+
for (const repo of config.repos) {
|
|
96
|
+
const repoDir = path.join(getReposDir(), repo.name);
|
|
97
|
+
if (fs.existsSync(repoDir)) {
|
|
98
|
+
const repoTemplates = (0, templates_1.loadTemplatesFromDir)(path.join(repoDir, 'templates'));
|
|
99
|
+
templates.push(...repoTemplates.map((t) => ({ ...t, repoName: repo.name })));
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
return templates;
|
|
103
|
+
}
|
|
104
|
+
async function listTemplates(options) {
|
|
105
|
+
const chalk = await getChalk();
|
|
106
|
+
const templates = await getAllTemplatesWithRepo(options?.repo);
|
|
107
|
+
if (templates.length === 0) {
|
|
108
|
+
console.log(chalk.yellow('\n⚠️ 没有找到模板'));
|
|
109
|
+
console.log(chalk.gray('请先添加并同步模板仓库:'));
|
|
110
|
+
console.log(chalk.gray(' prompt-plus repo add official https://github.com/LeeSeaside/prompt-plus-templates.git'));
|
|
111
|
+
console.log(chalk.gray(' prompt-plus repo sync\n'));
|
|
112
|
+
return;
|
|
113
|
+
}
|
|
114
|
+
console.log(chalk.cyan('\n📋 可用的提示词模板:\n'));
|
|
115
|
+
// 按仓库分组
|
|
116
|
+
const repoNames = [...new Set(templates.map((t) => t.repoName))];
|
|
117
|
+
for (const repoName of repoNames) {
|
|
118
|
+
console.log(chalk.magenta(`📦 ${repoName}`));
|
|
119
|
+
const repoTemplates = templates.filter((t) => t.repoName === repoName);
|
|
120
|
+
// 按分类分组
|
|
121
|
+
const categories = [...new Set(repoTemplates.map((t) => t.category))];
|
|
122
|
+
for (const category of categories) {
|
|
123
|
+
console.log(chalk.yellow(` [${category}]`));
|
|
124
|
+
const categoryTemplates = repoTemplates.filter((t) => t.category === category);
|
|
125
|
+
for (const template of categoryTemplates) {
|
|
126
|
+
console.log(chalk.white(` • ${template.name}`), chalk.gray(`- ${template.description}`));
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
console.log();
|
|
130
|
+
}
|
|
131
|
+
console.log(chalk.gray('使用 "prompt-plus use <模板名>" 或 "prompt-plus use" 交互式选择\n'));
|
|
132
|
+
}
|
|
133
|
+
async function useTemplate(templateName, options) {
|
|
134
|
+
const chalk = await getChalk();
|
|
135
|
+
const inquirer = await getInquirer();
|
|
136
|
+
const templates = await getAllTemplatesWithRepo(options?.repo);
|
|
137
|
+
let selectedTemplate;
|
|
138
|
+
if (templateName) {
|
|
139
|
+
selectedTemplate = templates.find((t) => t.name === templateName);
|
|
140
|
+
if (!selectedTemplate) {
|
|
141
|
+
console.log(chalk.red(`\n❌ 未找到模板: ${templateName}`));
|
|
142
|
+
console.log(chalk.gray('使用 "prompt-plus list" 查看可用模板\n'));
|
|
143
|
+
return;
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
else {
|
|
147
|
+
if (templates.length === 0) {
|
|
148
|
+
console.log(chalk.yellow('\n⚠️ 没有可用模板'));
|
|
149
|
+
console.log(chalk.gray('请先添加并同步模板仓库\n'));
|
|
150
|
+
return;
|
|
151
|
+
}
|
|
152
|
+
const choices = templates.map((t) => ({
|
|
153
|
+
name: `[${t.repoName}] ${t.name} - ${t.description}`,
|
|
154
|
+
value: t.name,
|
|
155
|
+
}));
|
|
156
|
+
const answer = await inquirer.prompt([
|
|
157
|
+
{
|
|
158
|
+
type: 'list',
|
|
159
|
+
name: 'template',
|
|
160
|
+
message: '请选择要使用的模板:',
|
|
161
|
+
choices,
|
|
162
|
+
},
|
|
163
|
+
]);
|
|
164
|
+
selectedTemplate = templates.find((t) => t.name === answer.template);
|
|
165
|
+
}
|
|
166
|
+
if (!selectedTemplate) {
|
|
167
|
+
console.log(chalk.red('\n❌ 模板选择失败'));
|
|
168
|
+
return;
|
|
169
|
+
}
|
|
170
|
+
const baseDir = options?.output || '.prompts';
|
|
171
|
+
const templatesDir = path.join(process.cwd(), baseDir, 'templates');
|
|
172
|
+
const generatedDir = path.join(process.cwd(), baseDir, 'generated');
|
|
173
|
+
if (!fs.existsSync(templatesDir)) {
|
|
174
|
+
fs.mkdirSync(templatesDir, { recursive: true });
|
|
175
|
+
}
|
|
176
|
+
if (!fs.existsSync(generatedDir)) {
|
|
177
|
+
fs.mkdirSync(generatedDir, { recursive: true });
|
|
178
|
+
}
|
|
179
|
+
const filePath = path.join(templatesDir, selectedTemplate.outputFileName);
|
|
180
|
+
fs.writeFileSync(filePath, selectedTemplate.content, 'utf-8');
|
|
181
|
+
console.log(chalk.green(`\n✅ 模板已生成: ${filePath}`));
|
|
182
|
+
console.log(chalk.cyan('\n📝 使用方法:'));
|
|
183
|
+
console.log(chalk.white(' 1. 打开生成的提示词文件'));
|
|
184
|
+
console.log(chalk.white(' 2. 复制内容到AI编辑器(Cursor/Trae等)'));
|
|
185
|
+
console.log(chalk.white(' 3. AI会分析你的项目并生成具体的开发提示词'));
|
|
186
|
+
console.log(chalk.white(` 4. 将AI生成的正式提示词保存到: ${chalk.yellow(baseDir + '/generated/')}`));
|
|
187
|
+
console.log(chalk.white(' 5. 使用正式提示词进行实际开发\n'));
|
|
188
|
+
console.log(chalk.gray(`📁 目录结构:`));
|
|
189
|
+
console.log(chalk.gray(` ${baseDir}/`));
|
|
190
|
+
console.log(chalk.gray(` ├── templates/ # 提示词模板`));
|
|
191
|
+
console.log(chalk.gray(` └── generated/ # 正式提示词\n`));
|
|
192
|
+
}
|
|
193
|
+
async function initConfig() {
|
|
194
|
+
const chalk = await getChalk();
|
|
195
|
+
const configPath = getGlobalConfigPath();
|
|
196
|
+
if (fs.existsSync(configPath)) {
|
|
197
|
+
console.log(chalk.yellow('\n⚠️ 配置文件已存在'));
|
|
198
|
+
console.log(chalk.gray(`路径: ${configPath}\n`));
|
|
199
|
+
return;
|
|
200
|
+
}
|
|
201
|
+
const defaultConfig = {
|
|
202
|
+
defaultRepo: '',
|
|
203
|
+
repos: [],
|
|
204
|
+
outputDir: '.prompts',
|
|
205
|
+
};
|
|
206
|
+
saveConfig(defaultConfig);
|
|
207
|
+
console.log(chalk.green('\n✅ 配置文件已创建'));
|
|
208
|
+
console.log(chalk.gray(`路径: ${configPath}`));
|
|
209
|
+
console.log(chalk.gray('\n下一步: 添加模板仓库'));
|
|
210
|
+
console.log(chalk.gray(' prompt-plus repo add official https://github.com/LeeSeaside/prompt-plus-templates.git\n'));
|
|
211
|
+
}
|
|
212
|
+
async function addRepo(name, url, options) {
|
|
213
|
+
const chalk = await getChalk();
|
|
214
|
+
const config = getConfig();
|
|
215
|
+
if (config.repos.find((r) => r.name === name)) {
|
|
216
|
+
console.log(chalk.yellow(`\n⚠️ 仓库 "${name}" 已存在\n`));
|
|
217
|
+
return;
|
|
218
|
+
}
|
|
219
|
+
config.repos.push({
|
|
220
|
+
name,
|
|
221
|
+
url,
|
|
222
|
+
branch: options?.branch || 'main',
|
|
223
|
+
});
|
|
224
|
+
saveConfig(config);
|
|
225
|
+
console.log(chalk.green(`\n✅ 已添加仓库: ${name}`));
|
|
226
|
+
console.log(chalk.gray(`使用 "prompt-plus repo sync ${name}" 同步模板\n`));
|
|
227
|
+
}
|
|
228
|
+
async function removeRepo(name) {
|
|
229
|
+
const chalk = await getChalk();
|
|
230
|
+
const config = getConfig();
|
|
231
|
+
const index = config.repos.findIndex((r) => r.name === name);
|
|
232
|
+
if (index === -1) {
|
|
233
|
+
console.log(chalk.red(`\n❌ 未找到仓库: ${name}\n`));
|
|
234
|
+
return;
|
|
235
|
+
}
|
|
236
|
+
config.repos.splice(index, 1);
|
|
237
|
+
saveConfig(config);
|
|
238
|
+
// 删除本地仓库目录
|
|
239
|
+
const repoDir = path.join(getReposDir(), name);
|
|
240
|
+
if (fs.existsSync(repoDir)) {
|
|
241
|
+
fs.rmSync(repoDir, { recursive: true, force: true });
|
|
242
|
+
}
|
|
243
|
+
console.log(chalk.green(`\n✅ 已移除仓库: ${name}\n`));
|
|
244
|
+
}
|
|
245
|
+
async function listRepos() {
|
|
246
|
+
const chalk = await getChalk();
|
|
247
|
+
const config = getConfig();
|
|
248
|
+
console.log(chalk.cyan('\n📦 模板仓库列表:\n'));
|
|
249
|
+
if (config.repos.length === 0) {
|
|
250
|
+
console.log(chalk.gray(' 暂无仓库,请先添加:'));
|
|
251
|
+
console.log(chalk.gray(' prompt-plus repo add official https://github.com/LeeSeaside/prompt-plus-templates.git\n'));
|
|
252
|
+
return;
|
|
253
|
+
}
|
|
254
|
+
for (const repo of config.repos) {
|
|
255
|
+
const synced = fs.existsSync(path.join(getReposDir(), repo.name));
|
|
256
|
+
const status = synced ? chalk.green('✓ 已同步') : chalk.yellow('未同步');
|
|
257
|
+
console.log(chalk.white(` • ${repo.name}`), chalk.gray(`- ${repo.url}`), status);
|
|
258
|
+
}
|
|
259
|
+
console.log(chalk.gray('\n使用 "prompt-plus repo add <name> <url>" 添加仓库'));
|
|
260
|
+
console.log(chalk.gray('使用 "prompt-plus repo sync [name]" 同步仓库\n'));
|
|
261
|
+
}
|
|
262
|
+
async function syncRepo(name) {
|
|
263
|
+
const chalk = await getChalk();
|
|
264
|
+
const config = getConfig();
|
|
265
|
+
const reposDir = getReposDir();
|
|
266
|
+
if (!fs.existsSync(reposDir)) {
|
|
267
|
+
fs.mkdirSync(reposDir, { recursive: true });
|
|
268
|
+
}
|
|
269
|
+
const reposToSync = name ? config.repos.filter((r) => r.name === name) : config.repos;
|
|
270
|
+
if (reposToSync.length === 0) {
|
|
271
|
+
if (name) {
|
|
272
|
+
console.log(chalk.red(`\n❌ 未找到仓库: ${name}\n`));
|
|
273
|
+
}
|
|
274
|
+
else {
|
|
275
|
+
console.log(chalk.yellow('\n⚠️ 没有配置任何仓库'));
|
|
276
|
+
console.log(chalk.gray('使用 "prompt-plus repo add <name> <url>" 添加仓库\n'));
|
|
277
|
+
}
|
|
278
|
+
return;
|
|
279
|
+
}
|
|
280
|
+
for (const repo of reposToSync) {
|
|
281
|
+
const repoDir = path.join(reposDir, repo.name);
|
|
282
|
+
console.log(chalk.cyan(`\n🔄 同步仓库: ${repo.name}...`));
|
|
283
|
+
try {
|
|
284
|
+
if (fs.existsSync(repoDir)) {
|
|
285
|
+
(0, child_process_1.execSync)(`git -C "${repoDir}" pull origin ${repo.branch || 'main'}`, { stdio: 'pipe' });
|
|
286
|
+
console.log(chalk.green(`✅ 已更新: ${repo.name}`));
|
|
287
|
+
}
|
|
288
|
+
else {
|
|
289
|
+
(0, child_process_1.execSync)(`git clone -b ${repo.branch || 'main'} "${repo.url}" "${repoDir}"`, { stdio: 'pipe' });
|
|
290
|
+
console.log(chalk.green(`✅ 已克隆: ${repo.name}`));
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
catch (error) {
|
|
294
|
+
console.log(chalk.red(`❌ 同步失败: ${repo.name}`));
|
|
295
|
+
console.log(chalk.gray(` ${error.message}`));
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
console.log();
|
|
299
|
+
}
|
package/dist/index.d.ts
ADDED
package/dist/index.js
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.loadTemplatesFromDir = void 0;
|
|
4
|
+
var templates_1 = require("./templates");
|
|
5
|
+
Object.defineProperty(exports, "loadTemplatesFromDir", { enumerable: true, get: function () { return templates_1.loadTemplatesFromDir; } });
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.loadTemplatesFromDir = loadTemplatesFromDir;
|
|
37
|
+
const fs = __importStar(require("fs"));
|
|
38
|
+
const path = __importStar(require("path"));
|
|
39
|
+
// 解析 Markdown Front Matter
|
|
40
|
+
function parseFrontMatter(content) {
|
|
41
|
+
const match = content.match(/^---\r?\n([\s\S]*?)\r?\n---\r?\n([\s\S]*)$/);
|
|
42
|
+
if (!match) {
|
|
43
|
+
return { meta: {}, body: content };
|
|
44
|
+
}
|
|
45
|
+
const meta = {};
|
|
46
|
+
const yamlContent = match[1];
|
|
47
|
+
const body = match[2];
|
|
48
|
+
yamlContent.split('\n').forEach((line) => {
|
|
49
|
+
const colonIndex = line.indexOf(':');
|
|
50
|
+
if (colonIndex > 0) {
|
|
51
|
+
const key = line.slice(0, colonIndex).trim();
|
|
52
|
+
const value = line.slice(colonIndex + 1).trim();
|
|
53
|
+
meta[key] = value;
|
|
54
|
+
}
|
|
55
|
+
});
|
|
56
|
+
return { meta, body };
|
|
57
|
+
}
|
|
58
|
+
// 从目录加载模板(支持 .md 和 .json)
|
|
59
|
+
function loadTemplatesFromDir(dir) {
|
|
60
|
+
if (!fs.existsSync(dir)) {
|
|
61
|
+
return [];
|
|
62
|
+
}
|
|
63
|
+
const templates = [];
|
|
64
|
+
const files = fs.readdirSync(dir);
|
|
65
|
+
for (const file of files) {
|
|
66
|
+
const filePath = path.join(dir, file);
|
|
67
|
+
try {
|
|
68
|
+
if (file.endsWith('.md') && file !== 'README.md') {
|
|
69
|
+
const content = fs.readFileSync(filePath, 'utf-8');
|
|
70
|
+
const { meta, body } = parseFrontMatter(content);
|
|
71
|
+
if (meta.name) {
|
|
72
|
+
templates.push({
|
|
73
|
+
name: meta.name,
|
|
74
|
+
description: meta.description || '',
|
|
75
|
+
category: meta.category || 'other',
|
|
76
|
+
outputFileName: meta.outputFileName || `${meta.name}-prompt.md`,
|
|
77
|
+
content: body.trim(),
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
else if (file.endsWith('.json')) {
|
|
82
|
+
const content = fs.readFileSync(filePath, 'utf-8');
|
|
83
|
+
const template = JSON.parse(content);
|
|
84
|
+
templates.push(template);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
catch {
|
|
88
|
+
// 忽略解析错误
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
return templates;
|
|
92
|
+
}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export interface Template {
|
|
2
|
+
name: string;
|
|
3
|
+
description: string;
|
|
4
|
+
category: string;
|
|
5
|
+
content: string;
|
|
6
|
+
outputFileName: string;
|
|
7
|
+
}
|
|
8
|
+
export interface RepoConfig {
|
|
9
|
+
name: string;
|
|
10
|
+
url: string;
|
|
11
|
+
branch?: string;
|
|
12
|
+
}
|
|
13
|
+
export interface PromptPlusConfig {
|
|
14
|
+
defaultRepo: string;
|
|
15
|
+
repos: RepoConfig[];
|
|
16
|
+
outputDir: string;
|
|
17
|
+
}
|
package/dist/types.js
ADDED
package/package.json
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "prompt-plus",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "AI提示词模板管理工具 - 生成符合项目规范的提示词",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"types": "dist/index.d.ts",
|
|
7
|
+
"bin": {
|
|
8
|
+
"prompt-plus": "./dist/cli.js",
|
|
9
|
+
"pp": "./dist/cli.js"
|
|
10
|
+
},
|
|
11
|
+
"files": [
|
|
12
|
+
"dist"
|
|
13
|
+
],
|
|
14
|
+
"scripts": {
|
|
15
|
+
"build": "tsc",
|
|
16
|
+
"prepublishOnly": "npm run build"
|
|
17
|
+
},
|
|
18
|
+
"keywords": [
|
|
19
|
+
"prompt",
|
|
20
|
+
"ai",
|
|
21
|
+
"template",
|
|
22
|
+
"cursor",
|
|
23
|
+
"copilot",
|
|
24
|
+
"chatgpt",
|
|
25
|
+
"claude",
|
|
26
|
+
"llm"
|
|
27
|
+
],
|
|
28
|
+
"author": "LeeSeaside",
|
|
29
|
+
"license": "MIT",
|
|
30
|
+
"repository": {
|
|
31
|
+
"type": "git",
|
|
32
|
+
"url": "https://github.com/LeeSeaside/prompt-plus.git"
|
|
33
|
+
},
|
|
34
|
+
"homepage": "https://github.com/LeeSeaside/prompt-plus#readme",
|
|
35
|
+
"bugs": {
|
|
36
|
+
"url": "https://github.com/LeeSeaside/prompt-plus/issues"
|
|
37
|
+
},
|
|
38
|
+
"devDependencies": {
|
|
39
|
+
"@types/inquirer": "^9.0.9",
|
|
40
|
+
"@types/node": "^20.10.0",
|
|
41
|
+
"typescript": "^5.3.0"
|
|
42
|
+
},
|
|
43
|
+
"dependencies": {
|
|
44
|
+
"chalk": "^5.3.0",
|
|
45
|
+
"commander": "^11.1.0",
|
|
46
|
+
"inquirer": "^9.2.12"
|
|
47
|
+
},
|
|
48
|
+
"engines": {
|
|
49
|
+
"node": ">=16.0.0"
|
|
50
|
+
}
|
|
51
|
+
}
|