draftgo-cli 4.0.23 → 4.0.25
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 +3 -1
- package/bin/draftgo.js +8 -8
- package/package.json +72 -72
- package/resources/custom-service-sdk/auth_test.go +1 -1
- package/resources/custom-service-sdk/manifest.json +11 -11
- package/resources/custom-service-sdk/platform.go +10 -3
- package/resources/custom-service-sdk/resources.go +1 -0
- package/resources/custom-service-sdk/resources_scope_test.go +10 -5
- package/resources/custom-service-sdk/sdk.go +4 -3
- package/resources/skill/SKILL.md +1 -1
- package/resources/skill/manifest.json +1 -1
- package/resources/skill/references/aihub.md +74 -74
- package/resources/skill/references/app-api.md +78 -78
- package/resources/skill/references/architecture.md +40 -40
- package/resources/skill/references/checkout.md +105 -105
- package/resources/skill/references/custom-services.md +4 -4
- package/resources/skill/references/data.md +168 -168
- package/resources/skill/references/methods.md +3 -0
- package/resources/skill/references/modules.md +47 -47
- package/resources/skill/references/runtime.md +95 -96
- package/resources/skill/story/SKILL.md +264 -264
- package/src/commands/help.js +72 -71
- package/src/commands/listTargets.js +12 -12
- package/src/commands/status.js +2 -2
- package/src/commands/uninstall.js +45 -45
- package/src/commands/update.js +24 -30
- package/src/customServices.js +5 -4
- package/src/detect.js +14 -14
- package/src/fsx.js +67 -67
- package/src/index.js +25 -25
- package/src/localRuntime/detect.js +76 -76
- package/src/localRuntime/mysqlClient.js +138 -138
- package/src/logger.js +37 -37
- package/src/mcp/client.js +586 -595
- package/src/mcp/hosts.js +520 -520
- package/src/mcp/protocol.js +167 -167
- package/src/prompt.js +94 -94
- package/src/updateCheck.js +16 -16
package/src/commands/help.js
CHANGED
|
@@ -1,38 +1,39 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
3
|
const { all } = require('../targets');
|
|
4
|
-
const { HOSTS } = require('../mcp/hosts');
|
|
5
|
-
const { getPackageVersion } = require('../skill');
|
|
6
|
-
|
|
7
|
-
function help() {
|
|
8
|
-
const targets = all.map((i) => ` ${i.name.padEnd(12)} ${i.displayName}`).join('\n');
|
|
9
|
-
const mcpTargets = HOSTS.map((host) => {
|
|
10
|
-
const status = host.supported === false ? 'unsupported' : host.path;
|
|
11
|
-
return ` ${host.name.padEnd(12)} ${status}`;
|
|
12
|
-
}).join('\n');
|
|
13
|
-
|
|
14
|
-
console.log(`draftgo v${getPackageVersion()} - DraftGo workbench CLI for AI coding agents
|
|
15
|
-
|
|
4
|
+
const { HOSTS } = require('../mcp/hosts');
|
|
5
|
+
const { getPackageVersion } = require('../skill');
|
|
6
|
+
|
|
7
|
+
function help() {
|
|
8
|
+
const targets = all.map((i) => ` ${i.name.padEnd(12)} ${i.displayName}`).join('\n');
|
|
9
|
+
const mcpTargets = HOSTS.map((host) => {
|
|
10
|
+
const status = host.supported === false ? 'unsupported' : host.path;
|
|
11
|
+
return ` ${host.name.padEnd(12)} ${status}`;
|
|
12
|
+
}).join('\n');
|
|
13
|
+
|
|
14
|
+
console.log(`draftgo v${getPackageVersion()} - DraftGo workbench CLI for AI coding agents
|
|
15
|
+
|
|
16
16
|
DraftGo shell baseline: React + Vite. Database Pages default to native HTML,
|
|
17
17
|
Tailwind CSS 4, and Basecoat UI; Oat UI remains an optional Web Components layer.
|
|
18
18
|
MCP handles live discovery and structured resources; complete page, navigation,
|
|
19
19
|
document, and custom-service bodies use checkout/commit outside MCP context.
|
|
20
20
|
The installed Skill routes agents to task-specific References and MCP tools.
|
|
21
|
-
|
|
22
|
-
Usage:
|
|
23
|
-
draftgo init [<target>...] Install the DraftGo Skill. No target = detect.
|
|
24
|
-
Use "all" to install every Skill target.
|
|
21
|
+
|
|
22
|
+
Usage:
|
|
23
|
+
draftgo init [<target>...] Install the DraftGo Skill. No target = detect.
|
|
24
|
+
Use "all" to install every Skill target.
|
|
25
25
|
draftgo update [<target>...] Fully update the global CLI, then atomically
|
|
26
|
-
refresh installed
|
|
27
|
-
|
|
28
|
-
|
|
26
|
+
refresh installed Skills. An explicit target
|
|
27
|
+
may also install that target when missing.
|
|
28
|
+
draftgo uninstall <target|all> Remove Skill files. --purge also removes
|
|
29
|
+
the entire .draftgo/ runtime directory.
|
|
29
30
|
draftgo status Show connection health, current scope, targets, and Skill version.
|
|
30
|
-
|
|
31
|
+
|
|
31
32
|
draftgo connect [<target>...] Verify and save server/API Key, then configure
|
|
32
|
-
a detected or explicit MCP host. This never
|
|
33
|
-
downloads DraftGo business resources.
|
|
34
|
-
draftgo mcp setup [<target>...] Merge project-level stdio MCP configuration.
|
|
35
|
-
draftgo mcp status [<target>...] Check host configuration and secret safety.
|
|
33
|
+
a detected or explicit MCP host. This never
|
|
34
|
+
downloads DraftGo business resources.
|
|
35
|
+
draftgo mcp setup [<target>...] Merge project-level stdio MCP configuration.
|
|
36
|
+
draftgo mcp status [<target>...] Check host configuration and secret safety.
|
|
36
37
|
draftgo mcp test Test project, resource, and API MCP calls.
|
|
37
38
|
draftgo mcp serve Bridge local stdio to the remote /mcp endpoint.
|
|
38
39
|
|
|
@@ -41,7 +42,7 @@ Usage:
|
|
|
41
42
|
Use --route/--title for exact selection.
|
|
42
43
|
draftgo checkout <type> <id...> Download a long-form body + verified base,
|
|
43
44
|
including custom-service worktrees.
|
|
44
|
-
--force explicitly replaces local changes.
|
|
45
|
+
--force explicitly replaces local changes.
|
|
45
46
|
draftgo check [custom-services <id...>]
|
|
46
47
|
Validate all checkouts or selected custom services.
|
|
47
48
|
--remote also compares remote hash/version.
|
|
@@ -73,20 +74,20 @@ Usage:
|
|
|
73
74
|
Publish current validated drafts; batch errors
|
|
74
75
|
report services already completed.
|
|
75
76
|
draftgo reconcile <type> <id...> Repair stale metadata only when local equals remote.
|
|
76
|
-
draftgo conflicts List unresolved conflicts; --all includes resolved.
|
|
77
|
-
draftgo conflict show <type> <id>
|
|
78
|
-
Show preserved base/local/remote paths.
|
|
79
|
-
draftgo conflict resolve <type> <id>
|
|
80
|
-
Mark a merged worktree file ready against the
|
|
81
|
-
preserved remote base; then check/diff/commit.
|
|
77
|
+
draftgo conflicts List unresolved conflicts; --all includes resolved.
|
|
78
|
+
draftgo conflict show <type> <id>
|
|
79
|
+
Show preserved base/local/remote paths.
|
|
80
|
+
draftgo conflict resolve <type> <id>
|
|
81
|
+
Mark a merged worktree file ready against the
|
|
82
|
+
preserved remote base; then check/diff/commit.
|
|
82
83
|
draftgo clean [--dry-run|--yes] Plan or remove all tmp and registered artifacts.
|
|
83
84
|
draftgo work start <item> Add an active item to .draftgo/worklog.md.
|
|
84
85
|
draftgo work add <item> Add a pending item.
|
|
85
86
|
draftgo work start-item <ref> Mark an item active; ref is number or date#number.
|
|
86
87
|
draftgo work complete <ref> Mark an item complete; --note appends evidence.
|
|
87
88
|
draftgo work show|list Show the worklog or its structured item list.
|
|
88
|
-
|
|
89
|
-
draftgo api <query> Search the live API contract through MCP.
|
|
89
|
+
|
|
90
|
+
draftgo api <query> Search the live API contract through MCP.
|
|
90
91
|
draftgo api describe <operation_id>
|
|
91
92
|
Describe one live API operation through MCP.
|
|
92
93
|
draftgo api call <operation_id> --input <json-file>
|
|
@@ -105,24 +106,24 @@ Usage:
|
|
|
105
106
|
Manage db_meta record policies (none|owner|all).
|
|
106
107
|
draftgo delete <operation_id> [id]
|
|
107
108
|
Confirm and call a live delete operation.
|
|
108
|
-
draftgo deploy [<type> <id...>] Check, then diff or commit checked-out content.
|
|
109
|
-
--delivery local needs no IDs; preview/deploy
|
|
110
|
-
require an explicit type and IDs.
|
|
109
|
+
draftgo deploy [<type> <id...>] Check, then diff or commit checked-out content.
|
|
110
|
+
--delivery local needs no IDs; preview/deploy
|
|
111
|
+
require an explicit type and IDs.
|
|
111
112
|
draftgo auto-push [<type> <id...>]
|
|
112
113
|
With config.auto_push=true, check and commit
|
|
113
114
|
changed checkouts. Any conflict stops the run.
|
|
114
115
|
draftgo local setup|start|stop|logs|status
|
|
115
116
|
Manage the project-local Docker stack.
|
|
116
|
-
draftgo list-targets List Skill installation targets.
|
|
117
|
-
draftgo -v | --version Print CLI version.
|
|
118
|
-
draftgo -h | --help Show this help.
|
|
119
|
-
|
|
120
|
-
Resource types:
|
|
117
|
+
draftgo list-targets List Skill installation targets.
|
|
118
|
+
draftgo -v | --version Print CLI version.
|
|
119
|
+
draftgo -h | --help Show this help.
|
|
120
|
+
|
|
121
|
+
Resource types:
|
|
121
122
|
pages | nav/navigations | docs/articles | custom-services
|
|
122
|
-
|
|
123
|
-
Important flags:
|
|
124
|
-
--project <dir> Operate on <dir> instead of the current directory.
|
|
125
|
-
--target <name,...> Select one or more MCP setup/status targets.
|
|
123
|
+
|
|
124
|
+
Important flags:
|
|
125
|
+
--project <dir> Operate on <dir> instead of the current directory.
|
|
126
|
+
--target <name,...> Select one or more MCP setup/status targets.
|
|
126
127
|
--server <url> (connect) DraftGo base URL.
|
|
127
128
|
--mcp-url <url> (connect) Explicit endpoint; standard /mcp derives the
|
|
128
129
|
base URL; custom paths also need --server.
|
|
@@ -130,11 +131,11 @@ Important flags:
|
|
|
130
131
|
--scope-type space --space-id <id>
|
|
131
132
|
(connect) Save a target space for workspace resources.
|
|
132
133
|
--timeout <ms> (connect/mcp test) Network timeout.
|
|
133
|
-
--allow-offline (connect) Save only after explicitly accepting a
|
|
134
|
-
failed MCP validation.
|
|
135
|
-
--no-mcp-setup (connect) Do not write host MCP configuration.
|
|
136
|
-
--force (init/checkout) Overwrite Skill or local changes.
|
|
137
|
-
--purge (uninstall) Also remove the .draftgo/ directory.
|
|
134
|
+
--allow-offline (connect) Save only after explicitly accepting a
|
|
135
|
+
failed MCP validation.
|
|
136
|
+
--no-mcp-setup (connect) Do not write host MCP configuration.
|
|
137
|
+
--force (init/checkout) Overwrite Skill or local changes.
|
|
138
|
+
--purge (uninstall) Also remove the .draftgo/ directory.
|
|
138
139
|
--skip-update-check (update) Refresh Skills without contacting npm.
|
|
139
140
|
--connect (init) Continue into DraftGo server connection.
|
|
140
141
|
--no-setup (init) Install the Skill without either setup flow.
|
|
@@ -150,8 +151,8 @@ Important flags:
|
|
|
150
151
|
--stat (diff) Print per-file and total change statistics.
|
|
151
152
|
--strict Treat check warnings as failures.
|
|
152
153
|
--remote (check) Compare checkout hashes/versions with remote.
|
|
153
|
-
--yes Skip supported confirmation prompts.
|
|
154
|
-
--operation-id <id> (delete) Select an operation explicitly.
|
|
154
|
+
--yes Skip supported confirmation prompts.
|
|
155
|
+
--operation-id <id> (delete) Select an operation explicitly.
|
|
155
156
|
--params <json> (api call/delete) Pass an API parameter object.
|
|
156
157
|
--input <file> (api call/delete/custom-service test) Read a UTF-8
|
|
157
158
|
JSON object.
|
|
@@ -176,23 +177,23 @@ Important flags:
|
|
|
176
177
|
fallback: DRAFTGO_BROWSER_PATH.
|
|
177
178
|
--selector <css> (verify) Require a visible element in top or iframe DOM.
|
|
178
179
|
--width/--height <px> (verify) Override the default 1440x900 desktop viewport.
|
|
179
|
-
|
|
180
|
-
Security:
|
|
180
|
+
|
|
181
|
+
Security:
|
|
181
182
|
.draftgo/config.json stores the server and API Key and is gitignored. Host MCP
|
|
182
183
|
files contain only "draftgo mcp serve"; they never contain the API Key.
|
|
183
|
-
|
|
184
|
-
MCP targets (project config or status):
|
|
185
|
-
${mcpTargets}
|
|
186
|
-
|
|
187
|
-
Skill targets:
|
|
188
|
-
${targets}
|
|
189
|
-
|
|
190
|
-
Examples:
|
|
191
|
-
draftgo init codex
|
|
184
|
+
|
|
185
|
+
MCP targets (project config or status):
|
|
186
|
+
${mcpTargets}
|
|
187
|
+
|
|
188
|
+
Skill targets:
|
|
189
|
+
${targets}
|
|
190
|
+
|
|
191
|
+
Examples:
|
|
192
|
+
draftgo init codex
|
|
192
193
|
draftgo connect codex --server https://draftgo.example --api-key <key>
|
|
193
194
|
draftgo mcp test
|
|
194
195
|
draftgo map --type pages --route /admin/channel-ops --summary --output json
|
|
195
|
-
draftgo checkout pages 42
|
|
196
|
+
draftgo checkout pages 42
|
|
196
197
|
draftgo verify pages 42
|
|
197
198
|
draftgo diff pages 42 --stat
|
|
198
199
|
draftgo commit pages 42
|
|
@@ -200,8 +201,8 @@ Examples:
|
|
|
200
201
|
draftgo test custom-services 12 --handler route:POST:/health --input request.json
|
|
201
202
|
draftgo work start "Build document management and role permissions"
|
|
202
203
|
draftgo work complete 1 --note "Verification and delivery passed"
|
|
203
|
-
draftgo deploy docs 7 --delivery preview
|
|
204
|
-
`);
|
|
205
|
-
}
|
|
206
|
-
|
|
207
|
-
module.exports = help;
|
|
204
|
+
draftgo deploy docs 7 --delivery preview
|
|
205
|
+
`);
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
module.exports = help;
|
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
3
|
const { all } = require('../targets');
|
|
4
|
-
|
|
5
|
-
function listTargets() {
|
|
6
|
-
console.log('draftgo 支持的 AI 工具(target):');
|
|
7
|
-
for (const t of all) {
|
|
8
|
-
console.log(` ${t.name.padEnd(12)} ${t.displayName}`);
|
|
9
|
-
}
|
|
10
|
-
return 0;
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
module.exports = listTargets;
|
|
4
|
+
|
|
5
|
+
function listTargets() {
|
|
6
|
+
console.log('draftgo 支持的 AI 工具(target):');
|
|
7
|
+
for (const t of all) {
|
|
8
|
+
console.log(` ${t.name.padEnd(12)} ${t.displayName}`);
|
|
9
|
+
}
|
|
10
|
+
return 0;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
module.exports = listTargets;
|
package/src/commands/status.js
CHANGED
|
@@ -1,52 +1,52 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
const log = require('../logger');
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const log = require('../logger');
|
|
4
4
|
const { all, resolveTargets } = require('../targets');
|
|
5
|
-
const { removePath } = require('../fsx');
|
|
6
|
-
const { dgDir } = require('../paths');
|
|
7
|
-
|
|
8
|
-
async function uninstall(projectDir, positional, flags) {
|
|
9
|
-
log.title('draftgo uninstall');
|
|
10
|
-
|
|
11
|
-
let resolved = [];
|
|
12
|
-
let unknown = [];
|
|
13
|
-
if (positional.length === 0) {
|
|
14
|
-
log.err('Please specify a target, or use `draftgo uninstall all` to remove every target.');
|
|
15
|
-
log.dim(` Supported targets: ${all.map((i) => i.name).join(', ')}`);
|
|
16
|
-
return 1;
|
|
17
|
-
}
|
|
18
|
-
if (positional.includes('all')) {
|
|
19
|
-
resolved = all.slice();
|
|
20
|
-
} else {
|
|
21
|
-
({ resolved, unknown } = resolveTargets(positional));
|
|
22
|
-
if (unknown.length) {
|
|
23
|
-
log.err(`未知 target:${unknown.join(', ')}`);
|
|
24
|
-
return 1;
|
|
25
|
-
}
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
log.step('移除入口文件');
|
|
29
|
-
for (const t of resolved) {
|
|
30
|
-
try {
|
|
31
|
-
const removed = t.uninstall(projectDir);
|
|
32
|
-
if (removed) log.ok(`${t.displayName} 入口已移除`);
|
|
33
|
-
else log.dim(`${t.displayName} 入口不存在,跳过`);
|
|
34
|
-
} catch (e) {
|
|
35
|
-
log.err(`${t.displayName} 卸载失败:${e.message}`);
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
// Each AI-tool skill directory is self-contained, so per-target uninstall
|
|
40
|
-
// already wiped its content above. Only --purge nukes runtime data under
|
|
5
|
+
const { removePath } = require('../fsx');
|
|
6
|
+
const { dgDir } = require('../paths');
|
|
7
|
+
|
|
8
|
+
async function uninstall(projectDir, positional, flags) {
|
|
9
|
+
log.title('draftgo uninstall');
|
|
10
|
+
|
|
11
|
+
let resolved = [];
|
|
12
|
+
let unknown = [];
|
|
13
|
+
if (positional.length === 0) {
|
|
14
|
+
log.err('Please specify a target, or use `draftgo uninstall all` to remove every target.');
|
|
15
|
+
log.dim(` Supported targets: ${all.map((i) => i.name).join(', ')}`);
|
|
16
|
+
return 1;
|
|
17
|
+
}
|
|
18
|
+
if (positional.includes('all')) {
|
|
19
|
+
resolved = all.slice();
|
|
20
|
+
} else {
|
|
21
|
+
({ resolved, unknown } = resolveTargets(positional));
|
|
22
|
+
if (unknown.length) {
|
|
23
|
+
log.err(`未知 target:${unknown.join(', ')}`);
|
|
24
|
+
return 1;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
log.step('移除入口文件');
|
|
29
|
+
for (const t of resolved) {
|
|
30
|
+
try {
|
|
31
|
+
const removed = t.uninstall(projectDir);
|
|
32
|
+
if (removed) log.ok(`${t.displayName} 入口已移除`);
|
|
33
|
+
else log.dim(`${t.displayName} 入口不存在,跳过`);
|
|
34
|
+
} catch (e) {
|
|
35
|
+
log.err(`${t.displayName} 卸载失败:${e.message}`);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
// Each AI-tool skill directory is self-contained, so per-target uninstall
|
|
40
|
+
// already wiped its content above. Only --purge nukes runtime data under
|
|
41
41
|
// .draftgo/ (config/worklog/lessons/cache etc.).
|
|
42
42
|
if (flags.purge) {
|
|
43
43
|
if (removePath(dgDir(projectDir))) {
|
|
44
44
|
log.warn('已使用 --purge:.draftgo/(含 config/worklog/lessons 等运行时数据)已删除。');
|
|
45
45
|
}
|
|
46
46
|
}
|
|
47
|
-
|
|
48
|
-
log.title('完成');
|
|
49
|
-
return 0;
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
module.exports = uninstall;
|
|
47
|
+
|
|
48
|
+
log.title('完成');
|
|
49
|
+
return 0;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
module.exports = uninstall;
|
package/src/commands/update.js
CHANGED
|
@@ -2,10 +2,9 @@
|
|
|
2
2
|
|
|
3
3
|
const { spawnSync } = require('child_process');
|
|
4
4
|
const log = require('../logger');
|
|
5
|
-
const { all,
|
|
5
|
+
const { all, resolveTargets } = require('../targets');
|
|
6
6
|
const { ensureRuntime, writeInstalledVersion, readInstalledVersion, getPackageVersion } = require('../skill');
|
|
7
7
|
const { fetchLatestVersion, cmpSemver } = require('../updateCheck');
|
|
8
|
-
const { detectTargets } = require('../detect');
|
|
9
8
|
const { readInstallMarker, installRelease } = require('../releaseInstall');
|
|
10
9
|
|
|
11
10
|
const REENTRY_FLAG = 'DRAFTGO_UPDATE_REENTERED';
|
|
@@ -16,6 +15,10 @@ function installedTargetsNotRefreshed(projectDir, refreshedTargets) {
|
|
|
16
15
|
!refreshed.has(target.name) && target.status(projectDir).installed);
|
|
17
16
|
}
|
|
18
17
|
|
|
18
|
+
function targetInstalled(projectDir, target) {
|
|
19
|
+
return typeof target.status === 'function' && target.status(projectDir).installed === true;
|
|
20
|
+
}
|
|
21
|
+
|
|
19
22
|
async function updateCliIfNeeded(projectDir, positional, flags) {
|
|
20
23
|
if (process.env[REENTRY_FLAG] === '1' || flags['skip-update-check'] || process.env.DRAFTGO_NO_UPDATE_CHECK === '1') {
|
|
21
24
|
return null;
|
|
@@ -66,7 +69,7 @@ async function updateCliIfNeeded(projectDir, positional, flags) {
|
|
|
66
69
|
}
|
|
67
70
|
return Number.isInteger(rerun.status) ? rerun.status : 1;
|
|
68
71
|
}
|
|
69
|
-
|
|
72
|
+
|
|
70
73
|
async function update(projectDir, positional, flags) {
|
|
71
74
|
log.title('draftgo update');
|
|
72
75
|
|
|
@@ -75,45 +78,36 @@ async function update(projectDir, positional, flags) {
|
|
|
75
78
|
|
|
76
79
|
const prev = readInstalledVersion(projectDir);
|
|
77
80
|
log.info(`当前已装 skill:${prev || '未安装'},CLI 版本:${getPackageVersion()}`);
|
|
78
|
-
|
|
79
|
-
//
|
|
80
|
-
//
|
|
81
|
-
|
|
82
|
-
// - names → refresh the specified targets
|
|
83
|
-
let resolved = [];
|
|
81
|
+
|
|
82
|
+
// Implicit update only refreshes existing Skills. An explicit target is a
|
|
83
|
+
// deliberate request and may install that target when it is missing.
|
|
84
|
+
let resolved = [];
|
|
84
85
|
let unknown = [];
|
|
85
86
|
|
|
86
|
-
if (positional.length === 0) {
|
|
87
|
-
|
|
88
|
-
for (const t of all) {
|
|
89
|
-
if (t.status(projectDir).installed) byTarget.set(t.name, t);
|
|
90
|
-
}
|
|
91
|
-
for (const name of detectTargets(projectDir)) {
|
|
92
|
-
if (byName[name]) byTarget.set(name, byName[name]);
|
|
93
|
-
}
|
|
94
|
-
resolved = Array.from(byTarget.values());
|
|
87
|
+
if (positional.length === 0 || positional.includes('all')) {
|
|
88
|
+
resolved = all.filter((target) => targetInstalled(projectDir, target));
|
|
95
89
|
if (resolved.length === 0) {
|
|
96
|
-
log.warn('
|
|
97
|
-
log.dim('
|
|
90
|
+
log.warn('未检测到已安装的 DraftGo Skill,无可刷新内容。');
|
|
91
|
+
log.dim(' 需要新增 AI 工具时,请使用 `draftgo init <target>`。');
|
|
98
92
|
return 0;
|
|
99
93
|
} else {
|
|
100
94
|
log.info(`刷新目标:${resolved.map((r) => r.displayName).join(', ')}`);
|
|
101
95
|
}
|
|
102
96
|
} else {
|
|
103
|
-
({ resolved, unknown } = resolveTargets(positional));
|
|
97
|
+
({ resolved, unknown } = resolveTargets(positional));
|
|
104
98
|
if (unknown.length) {
|
|
105
99
|
log.err(`未知 target:${unknown.join(', ')}`);
|
|
106
100
|
return 1;
|
|
107
101
|
}
|
|
108
102
|
}
|
|
109
|
-
|
|
103
|
+
|
|
110
104
|
ensureRuntime(projectDir);
|
|
111
105
|
log.step('用 CLI 内置版本覆盖各 AI 工具 skill 目录');
|
|
112
106
|
const failures = [];
|
|
113
107
|
for (const t of resolved) {
|
|
114
|
-
try {
|
|
115
|
-
const r = t.install(projectDir, { force: true });
|
|
116
|
-
log.ok(`${t.displayName.padEnd(16)} → ${r.path}`);
|
|
108
|
+
try {
|
|
109
|
+
const r = t.install(projectDir, { force: true });
|
|
110
|
+
log.ok(`${t.displayName.padEnd(16)} → ${r.path}`);
|
|
117
111
|
} catch (e) {
|
|
118
112
|
log.err(`${t.displayName} 更新失败:${e.message}`);
|
|
119
113
|
failures.push(t.displayName);
|
|
@@ -132,11 +126,11 @@ async function update(projectDir, positional, flags) {
|
|
|
132
126
|
} else {
|
|
133
127
|
writeInstalledVersion(projectDir);
|
|
134
128
|
}
|
|
135
|
-
|
|
136
|
-
log.title('完成');
|
|
137
|
-
return 0;
|
|
138
|
-
}
|
|
139
|
-
|
|
129
|
+
|
|
130
|
+
log.title('完成');
|
|
131
|
+
return 0;
|
|
132
|
+
}
|
|
133
|
+
|
|
140
134
|
module.exports = update;
|
|
141
135
|
module.exports.updateCliIfNeeded = updateCliIfNeeded;
|
|
142
136
|
module.exports.installedTargetsNotRefreshed = installedTargetsNotRefreshed;
|
package/src/customServices.js
CHANGED
|
@@ -316,7 +316,8 @@ async function commit(projectDir, ids, options = {}) {
|
|
|
316
316
|
if (entry.server !== config.server) throw new WorktreeError('CHECKOUT_SERVER_MISMATCH', 'Checkout belongs to a different DraftGo server.');
|
|
317
317
|
syncManagedDevelopmentFiles(entry.local_dir);
|
|
318
318
|
const state = localState(entry); if (!state.base_valid) throw new WorktreeError('BASE_HASH_MISMATCH', `Custom service ${id} base does not match its manifest.`);
|
|
319
|
-
|
|
319
|
+
const createDraft = Boolean(options.ensureDraft) && entry.checkout_source === 'live';
|
|
320
|
+
if (!state.modified && !createDraft) return { id, entry, state, unchanged: true };
|
|
320
321
|
const current = await metadata(config, id, options);
|
|
321
322
|
if (current.content_hash !== entry.base_hash || String(current.base_revision) !== String(entry.base_revision)) {
|
|
322
323
|
const remoteArchive = await download(config, current, options); const conflict = await writeConflict(projectDir, entry, current, remoteArchive);
|
|
@@ -406,7 +407,7 @@ function validationStale(error) {
|
|
|
406
407
|
&& error.details && error.details.reason === 'validation_stale';
|
|
407
408
|
}
|
|
408
409
|
async function validate(projectDir, id, options = {}) {
|
|
409
|
-
const config = options.config || loadProjectConfig(projectDir); await commit(projectDir, [id], { ...options, config });
|
|
410
|
+
const config = options.config || loadProjectConfig(projectDir); await commit(projectDir, [id], { ...options, config, ensureDraft: true });
|
|
410
411
|
const manifest = loadManifest(projectDir); const result = await validateCommitted(projectDir, id, config, manifest, options);
|
|
411
412
|
if (!result.cached) saveManifest(projectDir, manifest);
|
|
412
413
|
return result;
|
|
@@ -427,7 +428,7 @@ async function test(projectDir, id, input = {}, options = {}) {
|
|
|
427
428
|
let entry;
|
|
428
429
|
let revision;
|
|
429
430
|
if (source === 'draft') {
|
|
430
|
-
await commit(projectDir, [id], { ...options, config });
|
|
431
|
+
await commit(projectDir, [id], { ...options, config, ensureDraft: true });
|
|
431
432
|
manifest = loadManifest(projectDir);
|
|
432
433
|
const validation = await validateCommitted(projectDir, id, config, manifest, options);
|
|
433
434
|
entry = manifest.entries[entryKey(id)];
|
|
@@ -447,7 +448,7 @@ async function test(projectDir, id, input = {}, options = {}) {
|
|
|
447
448
|
}
|
|
448
449
|
async function publish(projectDir, ids, options = {}) {
|
|
449
450
|
const config = options.config || loadProjectConfig(projectDir); const targets = uniqueIDs(ids);
|
|
450
|
-
await commit(projectDir, targets, { ...options, config });
|
|
451
|
+
await commit(projectDir, targets, { ...options, config, ensureDraft: true });
|
|
451
452
|
const manifest = loadManifest(projectDir);
|
|
452
453
|
const validations = await Promise.all(targets.map((id) => validateCommitted(projectDir, id, config, manifest, options)));
|
|
453
454
|
if (validations.some((result) => !result.cached)) saveManifest(projectDir, manifest);
|
package/src/detect.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
3
|
const path = require('path');
|
|
4
4
|
const { exists } = require('./fsx');
|
|
5
5
|
const { platforms } = require('./platforms');
|
|
@@ -9,15 +9,15 @@ const { platforms } = require('./platforms');
|
|
|
9
9
|
const SIGNALS = Object.fromEntries(
|
|
10
10
|
platforms.map((p) => [p.name, p.signals || []])
|
|
11
11
|
);
|
|
12
|
-
|
|
13
|
-
function detectTargets(projectDir) {
|
|
14
|
-
const hits = [];
|
|
15
|
-
for (const [name, signals] of Object.entries(SIGNALS)) {
|
|
16
|
-
if (signals.some((s) => exists(path.join(projectDir, s)))) {
|
|
17
|
-
hits.push(name);
|
|
18
|
-
}
|
|
19
|
-
}
|
|
20
|
-
return hits;
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
module.exports = { SIGNALS, detectTargets };
|
|
12
|
+
|
|
13
|
+
function detectTargets(projectDir) {
|
|
14
|
+
const hits = [];
|
|
15
|
+
for (const [name, signals] of Object.entries(SIGNALS)) {
|
|
16
|
+
if (signals.some((s) => exists(path.join(projectDir, s)))) {
|
|
17
|
+
hits.push(name);
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
return hits;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
module.exports = { SIGNALS, detectTargets };
|