draftgo-cli 3.0.29 → 3.0.33
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/LICENSE +21 -0
- package/README.md +38 -139
- package/package.json +10 -2
- package/resources/skill/SKILL.md +61 -184
- package/resources/skill/init/SKILL.md +18 -66
- package/resources/skill/manifest.json +27 -0
- package/resources/skill/pull/SKILL.md +18 -52
- package/resources/skill/push/SKILL.md +30 -282
- package/resources/skill/references/aihub.md +86 -0
- package/resources/skill/{quickref → references}/api-endpoints.md +39 -13
- package/resources/skill/references/api.json +20248 -0
- package/resources/skill/{quickref → references}/app-api.md +40 -0
- package/resources/skill/{core → references}/architecture.md +2 -2
- package/resources/skill/references/chat-sdk.md +201 -0
- package/resources/skill/references/custom-services.md +308 -0
- package/resources/skill/{specs → references}/data.md +5 -5
- package/resources/skill/{rules → references}/frontend.md +41 -11
- package/resources/skill/{core → references}/modules.md +7 -5
- package/resources/skill/references/parallel.md +48 -0
- package/resources/skill/{specs → references}/runtime.md +1 -1
- package/resources/skill/scripts/draftgo_push.py +80 -12
- package/resources/skill/story/SKILL.md +11 -16
- package/src/cli.js +13 -7
- package/src/commandRegistry.js +34 -0
- package/src/commands/api.js +153 -8
- package/src/commands/help.js +24 -29
- package/src/commands/init.js +17 -18
- package/src/commands/local.js +9 -3
- package/src/commands/sync.js +1 -1
- package/src/commands/update.js +40 -12
- package/src/index.js +13 -57
- package/src/localdev/compose.js +44 -200
- package/src/localdev/index.js +116 -216
- package/src/localdev/mysqlClient.js +12 -9
- package/src/localdev/services.js +163 -0
- package/src/projectConfig.js +1 -1
- package/src/projectMap.js +17 -80
- package/src/skill.js +1 -1
- package/src/updateCheck.js +2 -12
- package/resources/skill/practices/anti-patterns.md +0 -80
- package/resources/skill/practices/best-practices.md +0 -60
- package/resources/skill/practices/dev-declaration.md +0 -114
- package/resources/skill/quickref/api.json +0 -17784
- package/resources/skill/rules/dev-workflow.md +0 -749
- package/resources/skill/rules/parallel.md +0 -263
- package/resources/skill/scripts/__pycache__/draftgo_pull.cpython-312.pyc +0 -0
- package/resources/skill/scripts/__pycache__/draftgo_push.cpython-312.pyc +0 -0
- package/resources/skill/specs/custom-services.md +0 -199
- package/src/commands/doctor.js +0 -54
- package/src/commands/new.js +0 -186
- package/src/commands/projectScript.js +0 -37
- package/src/commands/upgrade.js +0 -52
- /package/resources/skill/{specs → references}/db-relations.md +0 -0
- /package/resources/skill/{rules → references}/debugging-syntax.md +0 -0
- /package/resources/skill/{specs → references}/security.md +0 -0
- /package/resources/skill/{specs → references}/ui-protocol.md +0 -0
package/src/commands/new.js
DELETED
|
@@ -1,186 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
const path = require('path');
|
|
4
|
-
const fs = require('fs');
|
|
5
|
-
const log = require('../logger');
|
|
6
|
-
const { exists, ensureDir } = require('../fsx');
|
|
7
|
-
|
|
8
|
-
const TEMPLATES = {
|
|
9
|
-
page: (slug) => ({
|
|
10
|
-
indexEntry: {
|
|
11
|
-
title: slug,
|
|
12
|
-
route: `/${slug}`,
|
|
13
|
-
tag: null,
|
|
14
|
-
menu: null,
|
|
15
|
-
status: 'active',
|
|
16
|
-
permission: { default: 'public' },
|
|
17
|
-
html_file: `.draftgo/pages/page_new_${slug}.html`,
|
|
18
|
-
},
|
|
19
|
-
file: `.draftgo/pages/page_new_${slug}.html`,
|
|
20
|
-
content: `<!DOCTYPE html>
|
|
21
|
-
<html>
|
|
22
|
-
<head><meta charset="UTF-8"></head>
|
|
23
|
-
<body>
|
|
24
|
-
<script>
|
|
25
|
-
const App = window.parent?.App;
|
|
26
|
-
</script>
|
|
27
|
-
|
|
28
|
-
<div class="p-6">
|
|
29
|
-
<h1 class="text-2xl font-bold">${slug}</h1>
|
|
30
|
-
<p class="text-muted-foreground mt-2">页面内容</p>
|
|
31
|
-
</div>
|
|
32
|
-
</body>
|
|
33
|
-
</html>`,
|
|
34
|
-
}),
|
|
35
|
-
|
|
36
|
-
nav: (code) => ({
|
|
37
|
-
indexEntry: {
|
|
38
|
-
name: code,
|
|
39
|
-
code,
|
|
40
|
-
status: 'active',
|
|
41
|
-
order: 0,
|
|
42
|
-
html_file: `.draftgo/navigations/nav_new_${code}.html`,
|
|
43
|
-
},
|
|
44
|
-
file: `.draftgo/navigations/nav_new_${code}.html`,
|
|
45
|
-
content: `<nav class="flex items-center gap-4 px-4 h-14">
|
|
46
|
-
<a href="/" class="font-semibold">首页</a>
|
|
47
|
-
</nav>`,
|
|
48
|
-
}),
|
|
49
|
-
|
|
50
|
-
db_meta: (type) => ({
|
|
51
|
-
indexEntry: {
|
|
52
|
-
type,
|
|
53
|
-
label: type,
|
|
54
|
-
describe: '',
|
|
55
|
-
schema: {
|
|
56
|
-
type: 'object',
|
|
57
|
-
properties: {
|
|
58
|
-
title: { type: 'string', title: '标题', required: true, searchable: 'fuzzy' },
|
|
59
|
-
},
|
|
60
|
-
},
|
|
61
|
-
permission: {
|
|
62
|
-
public: { read: 'none', create: 'none', update: 'none', delete: 'none' },
|
|
63
|
-
login: { read: 'all', create: 'all', update: 'owner', delete: 'owner' },
|
|
64
|
-
admin: { read: 'all', create: 'all', update: 'all', delete: 'all' },
|
|
65
|
-
},
|
|
66
|
-
},
|
|
67
|
-
file: null,
|
|
68
|
-
content: null,
|
|
69
|
-
}),
|
|
70
|
-
|
|
71
|
-
script: (slug) => ({
|
|
72
|
-
indexEntry: {
|
|
73
|
-
name: slug,
|
|
74
|
-
slug,
|
|
75
|
-
mode: 'mixed',
|
|
76
|
-
language: 'go',
|
|
77
|
-
status: 'active',
|
|
78
|
-
config: {},
|
|
79
|
-
permission: { default: 'admin' },
|
|
80
|
-
code_file: `.draftgo/custom_scripts/script_new_${slug}.go`,
|
|
81
|
-
},
|
|
82
|
-
file: `.draftgo/custom_scripts/script_new_${slug}.go`,
|
|
83
|
-
content: `package main
|
|
84
|
-
|
|
85
|
-
import "draftgo/sdk"
|
|
86
|
-
|
|
87
|
-
// GET /api/x/${slug}/
|
|
88
|
-
func Register(app *sdk.App) {
|
|
89
|
-
app.Route("GET", "/", get${slug.replace(/[^A-Za-z0-9_]/g, '_')})
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
func get${slug.replace(/[^A-Za-z0-9_]/g, '_')}(ctx *sdk.Context) (any, error) {
|
|
93
|
-
return ctx.Respond(map[string]any{"message": "ok"}, 200, nil), nil
|
|
94
|
-
}
|
|
95
|
-
`,
|
|
96
|
-
}),
|
|
97
|
-
|
|
98
|
-
doc: (slug) => ({
|
|
99
|
-
indexEntry: {
|
|
100
|
-
title: slug,
|
|
101
|
-
slug,
|
|
102
|
-
status: 'published',
|
|
103
|
-
category_id: null,
|
|
104
|
-
content_file: `.draftgo/docs/articles/doc_new_${slug}.html`,
|
|
105
|
-
},
|
|
106
|
-
file: `.draftgo/docs/articles/doc_new_${slug}.html`,
|
|
107
|
-
content: `<!DOCTYPE html>\n<html>\n<head><meta charset="UTF-8"></head>\n<body>\n<div class="p-6">\n <h1 class="text-2xl font-bold">${slug}</h1>\n <p>文档内容</p>\n</div>\n</body>\n</html>`,
|
|
108
|
-
}),
|
|
109
|
-
};
|
|
110
|
-
|
|
111
|
-
const INDEX_MAP = {
|
|
112
|
-
page: 'pages/index.json',
|
|
113
|
-
nav: 'navigations/index.json',
|
|
114
|
-
db_meta: 'db_meta/index.json',
|
|
115
|
-
script: 'custom_scripts/index.json',
|
|
116
|
-
doc: 'docs/articles/index.json',
|
|
117
|
-
};
|
|
118
|
-
|
|
119
|
-
const PUSH_TYPE = {
|
|
120
|
-
page: 'pages',
|
|
121
|
-
nav: 'nav',
|
|
122
|
-
db_meta: 'db_meta',
|
|
123
|
-
script: 'custom_scripts',
|
|
124
|
-
doc: 'docs',
|
|
125
|
-
};
|
|
126
|
-
|
|
127
|
-
function newResource(projectDir, positional) {
|
|
128
|
-
const [type, slug] = positional;
|
|
129
|
-
|
|
130
|
-
if (!type || !TEMPLATES[type]) {
|
|
131
|
-
log.err(`用法:draftgo new <type> <slug>`);
|
|
132
|
-
log.dim(` 支持类型:${Object.keys(TEMPLATES).join(' | ')}`);
|
|
133
|
-
return 1;
|
|
134
|
-
}
|
|
135
|
-
if (!slug) {
|
|
136
|
-
log.err(`缺少 slug/name 参数,例如:draftgo new ${type} my-slug`);
|
|
137
|
-
return 1;
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
const draftgoDir = path.join(projectDir, '.draftgo');
|
|
141
|
-
if (!exists(draftgoDir)) {
|
|
142
|
-
log.err('未找到 .draftgo/,请先运行 draftgo connect 或 /draftgo init');
|
|
143
|
-
return 1;
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
const tpl = TEMPLATES[type](slug);
|
|
147
|
-
const indexRel = INDEX_MAP[type];
|
|
148
|
-
const indexPath = path.join(draftgoDir, indexRel);
|
|
149
|
-
|
|
150
|
-
if (!exists(indexPath)) {
|
|
151
|
-
log.err(`未找到 ${indexPath},请先运行 /draftgo pull`);
|
|
152
|
-
return 1;
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
// 追加 index 条目
|
|
156
|
-
const items = JSON.parse(fs.readFileSync(indexPath, 'utf8'));
|
|
157
|
-
|
|
158
|
-
// 检查重复
|
|
159
|
-
const dupKey = type === 'page' ? 'route' : type === 'nav' ? 'code' : type === 'db_meta' ? 'type' : type === 'script' ? 'slug' : 'key';
|
|
160
|
-
const dupVal = tpl.indexEntry[dupKey];
|
|
161
|
-
if (dupVal && items.some((it) => it[dupKey] === dupVal)) {
|
|
162
|
-
log.err(`已存在 ${dupKey}="${dupVal}",请换一个名称`);
|
|
163
|
-
return 1;
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
items.push(tpl.indexEntry);
|
|
167
|
-
fs.writeFileSync(indexPath, JSON.stringify(items, null, 2), 'utf8');
|
|
168
|
-
|
|
169
|
-
// 创建模板文件
|
|
170
|
-
if (tpl.file && tpl.content !== null) {
|
|
171
|
-
const filePath = path.join(projectDir, tpl.file);
|
|
172
|
-
ensureDir(path.dirname(filePath));
|
|
173
|
-
if (exists(filePath)) {
|
|
174
|
-
log.warn(`文件已存在,跳过:${tpl.file}`);
|
|
175
|
-
} else {
|
|
176
|
-
fs.writeFileSync(filePath, tpl.content, 'utf8');
|
|
177
|
-
log.ok(`已创建:${tpl.file}`);
|
|
178
|
-
}
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
log.ok(`已追加到 .draftgo/${indexRel}`);
|
|
182
|
-
log.dim(` 编辑完成后运行:draftgo push ${PUSH_TYPE[type]}`);
|
|
183
|
-
return 0;
|
|
184
|
-
}
|
|
185
|
-
|
|
186
|
-
module.exports = newResource;
|
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
const fs = require('fs');
|
|
4
|
-
const path = require('path');
|
|
5
|
-
const { spawnSync } = require('child_process');
|
|
6
|
-
const log = require('../logger');
|
|
7
|
-
|
|
8
|
-
function projectScript(projectDir, scriptName) {
|
|
9
|
-
const pkgPath = path.join(projectDir, 'package.json');
|
|
10
|
-
if (!fs.existsSync(pkgPath)) {
|
|
11
|
-
log.err(`当前项目没有 package.json,无法运行 draftgo ${scriptName}。`);
|
|
12
|
-
return 1;
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
let pkg;
|
|
16
|
-
try {
|
|
17
|
-
pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf8'));
|
|
18
|
-
} catch (err) {
|
|
19
|
-
log.err(`package.json 解析失败:${err.message}`);
|
|
20
|
-
return 1;
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
if (!pkg.scripts || !pkg.scripts[scriptName]) {
|
|
24
|
-
log.err(`package.json 中没有 scripts.${scriptName}。`);
|
|
25
|
-
return 1;
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
const npmCmd = process.platform === 'win32' ? 'npm.cmd' : 'npm';
|
|
29
|
-
const r = spawnSync(npmCmd, ['run', scriptName], {
|
|
30
|
-
cwd: projectDir,
|
|
31
|
-
stdio: 'inherit',
|
|
32
|
-
shell: false,
|
|
33
|
-
});
|
|
34
|
-
return r.status || 0;
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
module.exports = projectScript;
|
package/src/commands/upgrade.js
DELETED
|
@@ -1,52 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
const { spawnSync } = require('child_process');
|
|
4
|
-
const log = require('../logger');
|
|
5
|
-
const { getPackageVersion } = require('../skill');
|
|
6
|
-
const { fetchLatestVersion, cmpSemver } = require('../updateCheck');
|
|
7
|
-
|
|
8
|
-
const REENTRY_FLAG = 'DRAFTGO_UPGRADE_REENTERED';
|
|
9
|
-
|
|
10
|
-
async function upgrade(projectDir) {
|
|
11
|
-
if (process.env[REENTRY_FLAG] === '1') {
|
|
12
|
-
log.err('检测到重复升级重入,已停止以避免循环。');
|
|
13
|
-
return 1;
|
|
14
|
-
}
|
|
15
|
-
const current = getPackageVersion();
|
|
16
|
-
const latest = await fetchLatestVersion(5000, { force: true });
|
|
17
|
-
if (!latest) {
|
|
18
|
-
log.err('无法查询 npm 最新版本,未执行升级。');
|
|
19
|
-
return 1;
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
if (cmpSemver(latest, current) <= 0) {
|
|
23
|
-
log.ok(`CLI 已是最新:${current}`);
|
|
24
|
-
return require('./update')(projectDir, [], { 'skip-update-check': true });
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
const npm = process.platform === 'win32' ? 'npm.cmd' : 'npm';
|
|
28
|
-
log.step(`显式升级 draftgo-cli:${current} → ${latest}`);
|
|
29
|
-
const install = spawnSync(npm, ['install', '-g', `draftgo-cli@${latest}`], { stdio: 'inherit', shell: false });
|
|
30
|
-
if (install.error) {
|
|
31
|
-
log.err(`升级启动失败:${install.error.message}`);
|
|
32
|
-
return 1;
|
|
33
|
-
}
|
|
34
|
-
if (install.status !== 0) {
|
|
35
|
-
log.err(`npm install 返回码 ${install.status}`);
|
|
36
|
-
return Number.isInteger(install.status) ? install.status : 1;
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
const cmd = process.platform === 'win32' ? 'draftgo.cmd' : 'draftgo';
|
|
40
|
-
const rerun = spawnSync(cmd, ['update', '--project', projectDir, '--skip-update-check'], {
|
|
41
|
-
stdio: 'inherit',
|
|
42
|
-
shell: false,
|
|
43
|
-
env: { ...process.env, [REENTRY_FLAG]: '1' },
|
|
44
|
-
});
|
|
45
|
-
if (rerun.error) {
|
|
46
|
-
log.err(`新版 CLI 重跑失败:${rerun.error.message}`);
|
|
47
|
-
return 1;
|
|
48
|
-
}
|
|
49
|
-
return Number.isInteger(rerun.status) ? rerun.status : 1;
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
module.exports = upgrade;
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|