draftgo-cli 3.0.56 → 4.0.22
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 +169 -297
- package/package.json +12 -7
- package/resources/custom-service-sdk/ai.go +520 -0
- package/resources/custom-service-sdk/ai_test.go +156 -0
- package/resources/custom-service-sdk/billing.go +596 -0
- package/resources/custom-service-sdk/billing_test.go +150 -0
- package/resources/custom-service-sdk/go.mod +3 -0
- package/resources/custom-service-sdk/manifest.json +72 -0
- package/resources/custom-service-sdk/platform.go +360 -0
- package/resources/custom-service-sdk/platform_logger_test.go +24 -0
- package/resources/custom-service-sdk/registration_test.go +39 -0
- package/resources/custom-service-sdk/resources.go +246 -0
- package/resources/custom-service-sdk/resources_billing_test.go +115 -0
- package/resources/custom-service-sdk/resources_files_test.go +57 -0
- package/resources/custom-service-sdk/resources_scope_test.go +87 -0
- package/resources/custom-service-sdk/sdk.go +208 -0
- package/resources/skill/SKILL.md +36 -87
- package/resources/skill/init/SKILL.md +9 -14
- package/resources/skill/manifest.json +6 -2
- package/resources/skill/references/aihub.md +28 -5
- package/resources/skill/references/app-api.md +56 -6
- package/resources/skill/references/architecture.md +2 -2
- package/resources/skill/references/chat-sdk.md +4 -2
- package/resources/skill/references/checkout.md +21 -7
- package/resources/skill/references/custom-services.md +124 -222
- package/resources/skill/references/data.md +22 -6
- package/resources/skill/references/delivery.md +33 -0
- package/resources/skill/references/diagnostics.md +51 -0
- package/resources/skill/references/frontend.md +93 -499
- package/resources/skill/references/mcp.md +65 -101
- package/resources/skill/references/methods.md +189 -0
- package/resources/skill/references/modules.md +36 -8
- package/resources/skill/references/runtime.md +26 -3
- package/resources/skill/story/SKILL.md +1 -2
- package/src/apiContractCache.js +112 -0
- package/src/cli.js +24 -20
- package/src/commandRegistry.js +15 -12
- package/src/commands/api.js +41 -10
- package/src/commands/apiKey.js +34 -0
- package/src/commands/capabilities.js +93 -0
- package/src/commands/check.js +1 -10
- package/src/commands/checkout.js +1 -1
- package/src/commands/commit.js +1 -1
- package/src/commands/components.js +550 -0
- package/src/commands/conflict.js +1 -1
- package/src/commands/connect.js +18 -8
- package/src/commands/customService.js +22 -8
- package/src/commands/dataRange.js +33 -0
- package/src/commands/delete.js +34 -46
- package/src/commands/deploy.js +1 -1
- package/src/commands/diff.js +18 -2
- package/src/commands/grant.js +29 -0
- package/src/commands/group.js +38 -0
- package/src/commands/help.js +80 -51
- package/src/commands/init.js +6 -12
- package/src/commands/listTargets.js +1 -1
- package/src/commands/local.js +2 -6
- package/src/commands/map.js +145 -28
- package/src/commands/mcp.js +2 -2
- package/src/commands/reconcile.js +1 -1
- package/src/commands/role.js +32 -0
- package/src/commands/space.js +41 -0
- package/src/commands/status.js +111 -8
- package/src/commands/uninstall.js +3 -3
- package/src/commands/update.js +24 -12
- package/src/commands/verify.js +118 -21
- package/src/commands/{verifyUi.js → visualVerify.js} +28 -116
- package/src/commands/worklog.js +90 -0
- package/src/consoleEncoding.js +34 -0
- package/src/contractCompatibility.js +57 -0
- package/src/customServices.js +278 -41
- package/src/diffReport.js +106 -0
- package/src/index.js +2 -0
- package/src/{localdev → localRuntime}/compose.js +14 -17
- package/src/{localdev → localRuntime}/detect.js +1 -1
- package/src/{localdev → localRuntime}/index.js +22 -23
- package/src/{localdev → localRuntime}/mysqlClient.js +1 -1
- package/src/{localdev → localRuntime}/services.js +28 -37
- package/src/mcp/client.js +11 -2
- package/src/mcp/protocol.js +2 -2
- package/src/mcp/tools.js +14 -1
- package/src/platforms.js +9 -0
- package/src/projectConfig.js +8 -4
- package/src/releaseInstall.js +105 -0
- package/src/{installers/index.js → targets.js} +3 -5
- package/src/updateCheck.js +48 -28
- package/src/worklog.js +275 -0
- package/src/workspaceHealth.js +1 -1
- package/src/worktree/backend.js +1 -1
- package/src/worktree/index.js +86 -51
- package/src/changelog.js +0 -276
- package/src/commands/changelog.js +0 -24
- package/src/commands/localDev.js +0 -9
- package/src/commands/sync.js +0 -46
- package/src/commands/task.js +0 -408
- package/src/commands/verifyUiCompat.js +0 -16
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
const fs = require('fs');
|
|
4
|
+
const path = require('path');
|
|
4
5
|
const log = require('../logger');
|
|
5
6
|
const services = require('../customServices');
|
|
7
|
+
const { report, formatSummary, formatStat } = require('../diffReport');
|
|
6
8
|
|
|
7
9
|
function ids(positional) { return positional.map(String).filter(Boolean); }
|
|
8
|
-
const TYPE_ALIASES = new Set(['custom-services', 'custom-service', 'custom_services', 'custom_service', 'services', 'scripts', 'custom_scripts']);
|
|
9
10
|
function isServiceType(value) {
|
|
10
|
-
return
|
|
11
|
+
return String(value || '').toLowerCase() === 'custom-services';
|
|
11
12
|
}
|
|
12
13
|
function serviceIds(positional) {
|
|
13
14
|
const values = ids(positional);
|
|
14
|
-
|
|
15
|
-
return values;
|
|
15
|
+
return isServiceType(values[0]) ? values.slice(1) : [];
|
|
16
16
|
}
|
|
17
17
|
function output(flags, value) {
|
|
18
18
|
if (flags.output === 'json') console.log(JSON.stringify(value, null, 2));
|
|
@@ -30,9 +30,10 @@ async function checkout(projectDir, positional, flags = {}) {
|
|
|
30
30
|
async function commit(projectDir, positional, flags = {}) {
|
|
31
31
|
const values = ids(positional);
|
|
32
32
|
if (!values.length) { log.err('Usage: draftgo commit custom-services <id...>'); return 1; }
|
|
33
|
-
|
|
33
|
+
// The user-facing custom-service commit is a complete delivery operation.
|
|
34
|
+
const result = await services.publish(projectDir, values);
|
|
34
35
|
if (flags.output === 'json') output(flags, result);
|
|
35
|
-
else result.forEach((item) => log.ok(`custom service ${item.resource_id}:
|
|
36
|
+
else result.forEach((item) => log.ok(`custom service ${item.id || item.resource_id}: published (commit + validate + publish)`));
|
|
36
37
|
return 0;
|
|
37
38
|
}
|
|
38
39
|
|
|
@@ -40,7 +41,18 @@ async function diff(projectDir, positional, flags = {}) {
|
|
|
40
41
|
const id = positional[0];
|
|
41
42
|
if (!id) { log.err('Usage: draftgo diff custom-services <id>'); return 1; }
|
|
42
43
|
const result = services.diff(projectDir, id);
|
|
43
|
-
|
|
44
|
+
const concise = Boolean(flags.stat || flags.summary);
|
|
45
|
+
const value = concise ? report(result.entry, result.file_outputs.map((file) => ({
|
|
46
|
+
path: file.filename,
|
|
47
|
+
changed: file.changed,
|
|
48
|
+
output: file.output,
|
|
49
|
+
base_path: path.join(result.entry.base_dir, file.filename),
|
|
50
|
+
local_path: path.join(result.entry.local_dir, file.filename),
|
|
51
|
+
}))) : null;
|
|
52
|
+
if (flags.output === 'json' && concise) output(flags, value);
|
|
53
|
+
else if (flags.output === 'json') output(flags, result);
|
|
54
|
+
else if (flags.stat) process.stdout.write(formatStat(value));
|
|
55
|
+
else if (flags.summary) process.stdout.write(formatSummary(value));
|
|
44
56
|
else if (result.changed) process.stdout.write(result.output);
|
|
45
57
|
else log.dim(`custom service ${id}: no local changes`);
|
|
46
58
|
return 0;
|
|
@@ -62,8 +74,10 @@ async function test(projectDir, positional, flags = {}) {
|
|
|
62
74
|
const readJSON = (value) => value ? JSON.parse(fs.readFileSync(String(value), 'utf8')) : undefined;
|
|
63
75
|
const policy = String(flags['side-effect-policy'] || 'deny').toLowerCase();
|
|
64
76
|
if (!['deny', 'mock', 'live'].includes(policy)) throw new Error('--side-effect-policy must be deny, mock, or live.');
|
|
77
|
+
const source = String(flags.source || 'draft').toLowerCase();
|
|
78
|
+
if (!['auto', 'draft', 'published'].includes(source)) throw new Error('--source must be auto, draft, or published.');
|
|
65
79
|
const result = await services.test(projectDir, id, input, { handler: flags.handler, headers: readJSON(flags.headers), user: readJSON(flags.user),
|
|
66
|
-
testWrite: Boolean(flags['test-write']), sideEffectPolicy: policy });
|
|
80
|
+
testWrite: Boolean(flags['test-write']), sideEffectPolicy: policy, source });
|
|
67
81
|
if (flags.output === 'json') output(flags, result);
|
|
68
82
|
else log[result.status === 'success' ? 'ok' : 'err'](`custom service ${id}: ${result.status}`);
|
|
69
83
|
return result.status === 'success' ? 0 : 1;
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const log = require('../logger');
|
|
4
|
+
const { callOperation } = require('./api');
|
|
5
|
+
|
|
6
|
+
// DataRange is represented by db_meta record policies; it is not a second
|
|
7
|
+
// authorization scope or a free-form client-side filter.
|
|
8
|
+
const OPERATIONS = Object.freeze({
|
|
9
|
+
list: 'list_meta_api_db_meta_get',
|
|
10
|
+
create: 'create_meta_api_db_meta_post',
|
|
11
|
+
get: 'get_meta_api_db_meta__type__get',
|
|
12
|
+
update: 'update_meta_api_db_meta__id__put',
|
|
13
|
+
batch: 'update_meta_batch_api_db_meta_batch_patch',
|
|
14
|
+
delete: 'delete_meta_api_db_meta__id__delete',
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
function operationKey(value) {
|
|
18
|
+
const action = String(value || 'list').trim().toLowerCase();
|
|
19
|
+
return OPERATIONS[action] ? action : '';
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
async function dataRangeCommand(projectDir, positional, flags = {}) {
|
|
23
|
+
const action = operationKey(positional[0]);
|
|
24
|
+
if (!action) {
|
|
25
|
+
log.err('Usage: draftgo data-range list|create|get|update|batch|delete --input <json-file>');
|
|
26
|
+
return 1;
|
|
27
|
+
}
|
|
28
|
+
return callOperation(projectDir, OPERATIONS[action], flags);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
module.exports = dataRangeCommand;
|
|
32
|
+
module.exports.OPERATIONS = OPERATIONS;
|
|
33
|
+
module.exports.operationKey = operationKey;
|
package/src/commands/delete.js
CHANGED
|
@@ -6,23 +6,13 @@ const log = require('../logger');
|
|
|
6
6
|
const { confirm } = require('../prompt');
|
|
7
7
|
const { loadProjectConfig } = require('../projectConfig');
|
|
8
8
|
const { TOOL_NAMES, openToolSession, callStructured } = require('../mcp/tools');
|
|
9
|
-
|
|
10
|
-
const
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
if (Array.isArray(value)) return value;
|
|
17
|
-
if (!value || typeof value !== 'object') return [];
|
|
18
|
-
if (Array.isArray(value.items)) return value.items;
|
|
19
|
-
if (Array.isArray(value.operations)) return value.operations;
|
|
20
|
-
return value.data ? resultItems(value.data) : [];
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
function operationId(value) {
|
|
24
|
-
return value && (value.operation_id || value.operationId || value.id);
|
|
25
|
-
}
|
|
9
|
+
const { cachedDescription, normalizeDescription, storeDescription } = require('../apiContractCache');
|
|
10
|
+
const {
|
|
11
|
+
isContractCompatibilityError,
|
|
12
|
+
isHardContractIncompatibility,
|
|
13
|
+
sameOperationContract,
|
|
14
|
+
incompatibleOperationError,
|
|
15
|
+
} = require('../contractCompatibility');
|
|
26
16
|
|
|
27
17
|
function readParams(projectDir, flags) {
|
|
28
18
|
const raw = flags.params ? String(flags.params)
|
|
@@ -45,40 +35,25 @@ function pathParameterName(description) {
|
|
|
45
35
|
async function deleteResource(projectDir, positional, flags = {}) {
|
|
46
36
|
if (!positional.length && !flags['operation-id']) {
|
|
47
37
|
log.err('Usage: draftgo delete <operation_id> [id] [--params JSON]');
|
|
48
|
-
log.dim(' Legacy form is supported when discovery is unambiguous: draftgo delete <type> <id>.');
|
|
49
38
|
return 1;
|
|
50
39
|
}
|
|
51
40
|
const config = loadProjectConfig(projectDir);
|
|
52
41
|
const session = await openToolSession(config, [
|
|
53
|
-
TOOL_NAMES.
|
|
42
|
+
TOOL_NAMES.apiDescribe, TOOL_NAMES.apiCall,
|
|
54
43
|
]);
|
|
55
44
|
|
|
56
|
-
const
|
|
57
|
-
const
|
|
58
|
-
let selectedOperation = flags['operation-id'] ? String(flags['operation-id']) : (legacy ? null : first);
|
|
59
|
-
const resourceId = legacy ? positional[1] : positional[1];
|
|
60
|
-
if (legacy) {
|
|
61
|
-
if (!resourceId) {
|
|
62
|
-
log.err('Legacy delete form requires a resource id.');
|
|
63
|
-
return 1;
|
|
64
|
-
}
|
|
65
|
-
const search = await callStructured(session, TOOL_NAMES.apiSearch, { query: `delete ${first}` });
|
|
66
|
-
const candidates = resultItems(search).filter((item) => operationId(item)
|
|
67
|
-
&& (!item.method || String(item.method).toUpperCase() === 'DELETE'));
|
|
68
|
-
if (candidates.length !== 1) {
|
|
69
|
-
log.err(`Delete operation discovery was ambiguous (${candidates.length} matches).`);
|
|
70
|
-
log.dim(` Run \`draftgo api delete ${first}\`, then pass --operation-id explicitly.`);
|
|
71
|
-
return 1;
|
|
72
|
-
}
|
|
73
|
-
selectedOperation = operationId(candidates[0]);
|
|
74
|
-
}
|
|
45
|
+
const selectedOperation = flags['operation-id'] ? String(flags['operation-id']) : String(positional[0]);
|
|
46
|
+
const resourceId = positional[1];
|
|
75
47
|
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
48
|
+
let contract = cachedDescription(projectDir, config.server, selectedOperation);
|
|
49
|
+
if (!contract) {
|
|
50
|
+
const described = await callStructured(session, TOOL_NAMES.apiDescribe, { operation_id: selectedOperation });
|
|
51
|
+
contract = storeDescription(projectDir, config.server, described) || normalizeDescription(described);
|
|
52
|
+
}
|
|
53
|
+
if (!contract) throw new Error('DraftGo API description is missing contract revision metadata.');
|
|
79
54
|
const params = readParams(projectDir, flags);
|
|
80
55
|
if (resourceId && Object.keys(params).length === 0) {
|
|
81
|
-
const parameterName = pathParameterName(
|
|
56
|
+
const parameterName = pathParameterName(contract.operation);
|
|
82
57
|
if (!parameterName) {
|
|
83
58
|
log.err('The operation does not expose exactly one path parameter; provide --params JSON explicitly.');
|
|
84
59
|
return 1;
|
|
@@ -89,11 +64,24 @@ async function deleteResource(projectDir, positional, flags = {}) {
|
|
|
89
64
|
const approved = await confirm(`Call destructive DraftGo operation ${selectedOperation}?`, { default: false });
|
|
90
65
|
if (!approved) return 0;
|
|
91
66
|
}
|
|
92
|
-
const
|
|
93
|
-
...params,
|
|
94
|
-
operation_id: selectedOperation,
|
|
95
|
-
confirm: true,
|
|
67
|
+
const invoke = () => callStructured(session, TOOL_NAMES.apiCall, {
|
|
68
|
+
...params, operation_id: selectedOperation, registry_revision: contract.registry_revision, confirm: true,
|
|
96
69
|
});
|
|
70
|
+
let result;
|
|
71
|
+
try {
|
|
72
|
+
result = await invoke();
|
|
73
|
+
} catch (error) {
|
|
74
|
+
if (!isContractCompatibilityError(error)) throw error;
|
|
75
|
+
if (isHardContractIncompatibility(error)) throw incompatibleOperationError(selectedOperation, error);
|
|
76
|
+
const previousContract = contract;
|
|
77
|
+
const described = await callStructured(session, TOOL_NAMES.apiDescribe, { operation_id: selectedOperation });
|
|
78
|
+
contract = storeDescription(projectDir, config.server, described) || normalizeDescription(described);
|
|
79
|
+
if (!contract) throw new Error('DraftGo API description is missing contract revision metadata.');
|
|
80
|
+
if (!sameOperationContract(previousContract, contract)) {
|
|
81
|
+
throw incompatibleOperationError(selectedOperation, error);
|
|
82
|
+
}
|
|
83
|
+
result = await invoke();
|
|
84
|
+
}
|
|
97
85
|
if (flags.output === 'json') console.log(JSON.stringify(result, null, 2));
|
|
98
86
|
else log.ok(`DraftGo operation completed: ${selectedOperation}`);
|
|
99
87
|
return 0;
|
package/src/commands/deploy.js
CHANGED
|
@@ -23,7 +23,7 @@ async function deploy(projectDir, positional, flags = {}) {
|
|
|
23
23
|
|
|
24
24
|
const [resourceType, ...ids] = positional;
|
|
25
25
|
if (!resourceType || !ids.length) {
|
|
26
|
-
log.err('
|
|
26
|
+
log.err('Usage: draftgo deploy <pages|nav|docs> <id...> --delivery preview|deploy');
|
|
27
27
|
return 1;
|
|
28
28
|
}
|
|
29
29
|
if (delivery === 'preview') {
|
package/src/commands/diff.js
CHANGED
|
@@ -2,19 +2,35 @@
|
|
|
2
2
|
|
|
3
3
|
const log = require('../logger');
|
|
4
4
|
const { diffResource } = require('../worktree');
|
|
5
|
+
const { report, formatSummary, formatStat } = require('../diffReport');
|
|
6
|
+
const { absolutePath } = require('../worktree/manifest');
|
|
5
7
|
|
|
6
8
|
function diff(projectDir, positional, flags = {}) {
|
|
7
9
|
const [resourceType, resourceId] = positional;
|
|
8
10
|
if (!resourceType || !resourceId) {
|
|
9
|
-
log.err('Usage: draftgo diff <pages|nav|docs> <id>');
|
|
11
|
+
log.err('Usage: draftgo diff <pages|nav|docs|custom-services> <id>');
|
|
10
12
|
return 1;
|
|
11
13
|
}
|
|
12
14
|
if (require('./customService').isServiceType(resourceType)) {
|
|
13
15
|
return require('./customService').diff(projectDir, [resourceId], flags);
|
|
14
16
|
}
|
|
15
17
|
const result = diffResource(projectDir, resourceType, resourceId);
|
|
16
|
-
|
|
18
|
+
const concise = Boolean(flags.stat || flags.summary);
|
|
19
|
+
const value = concise ? report(result.entry, [{
|
|
20
|
+
path: result.entry.local_path,
|
|
21
|
+
changed: result.changed,
|
|
22
|
+
output: result.output,
|
|
23
|
+
base_path: absolutePath(projectDir, result.entry.base_path),
|
|
24
|
+
local_path: absolutePath(projectDir, result.entry.local_path),
|
|
25
|
+
}]) : null;
|
|
26
|
+
if (flags.output === 'json' && concise) {
|
|
27
|
+
console.log(JSON.stringify(value, null, 2));
|
|
28
|
+
} else if (flags.output === 'json') {
|
|
17
29
|
console.log(JSON.stringify({ changed: result.changed, entry: result.entry, diff: result.output }, null, 2));
|
|
30
|
+
} else if (flags.stat) {
|
|
31
|
+
process.stdout.write(formatStat(value));
|
|
32
|
+
} else if (flags.summary) {
|
|
33
|
+
process.stdout.write(formatSummary(value));
|
|
18
34
|
} else if (result.changed) {
|
|
19
35
|
process.stdout.write(result.output);
|
|
20
36
|
} else {
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const log = require('../logger');
|
|
4
|
+
const { callOperation } = require('./api');
|
|
5
|
+
|
|
6
|
+
const OPERATIONS = Object.freeze({
|
|
7
|
+
list: 'listAccessGrants',
|
|
8
|
+
create: 'createAccessGrant',
|
|
9
|
+
get: 'getAccessGrant',
|
|
10
|
+
revoke: 'revokeAccessGrant',
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
function operationKey(value) {
|
|
14
|
+
const action = String(value || 'list').trim().toLowerCase();
|
|
15
|
+
return OPERATIONS[action] ? action : '';
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
async function grantCommand(projectDir, positional, flags = {}) {
|
|
19
|
+
const action = operationKey(positional[0]);
|
|
20
|
+
if (!action) {
|
|
21
|
+
log.err('Usage: draftgo grant list|create|get|revoke [--input <json-file>]');
|
|
22
|
+
return 1;
|
|
23
|
+
}
|
|
24
|
+
return callOperation(projectDir, OPERATIONS[action], flags);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
module.exports = grantCommand;
|
|
28
|
+
module.exports.OPERATIONS = OPERATIONS;
|
|
29
|
+
module.exports.operationKey = operationKey;
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const log = require('../logger');
|
|
4
|
+
const { callOperation } = require('./api');
|
|
5
|
+
|
|
6
|
+
const OPERATIONS = Object.freeze({
|
|
7
|
+
list: 'listUserGroups',
|
|
8
|
+
create: 'createUserGroup',
|
|
9
|
+
get: 'getUserGroup',
|
|
10
|
+
update: 'updateUserGroup',
|
|
11
|
+
replace: 'replaceUserGroup',
|
|
12
|
+
remove: 'removeUserGroup',
|
|
13
|
+
'members.list': 'listUserGroupMembers',
|
|
14
|
+
'members.add': 'addUserGroupMember',
|
|
15
|
+
'members.remove': 'removeUserGroupMember',
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
function operationKey(parts) {
|
|
19
|
+
const values = parts.map((part) => String(part || '').trim().toLowerCase()).filter(Boolean);
|
|
20
|
+
if (values.length === 1) return values[0] === 'delete' ? 'remove' : values[0];
|
|
21
|
+
if (values.length === 2 && ['member', 'members'].includes(values[0])) {
|
|
22
|
+
return `members.${values[1] === 'delete' ? 'remove' : values[1]}`;
|
|
23
|
+
}
|
|
24
|
+
return '';
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
async function groupCommand(projectDir, positional, flags = {}) {
|
|
28
|
+
const key = operationKey(positional);
|
|
29
|
+
if (!OPERATIONS[key]) {
|
|
30
|
+
log.err('Usage: draftgo group list|create|get|update|replace|remove | members list|add|remove [--input <json-file>]');
|
|
31
|
+
return 1;
|
|
32
|
+
}
|
|
33
|
+
return callOperation(projectDir, OPERATIONS[key], flags);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
module.exports = groupCommand;
|
|
37
|
+
module.exports.OPERATIONS = OPERATIONS;
|
|
38
|
+
module.exports.operationKey = operationKey;
|
package/src/commands/help.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
const { all } = require('../
|
|
3
|
+
const { all } = require('../targets');
|
|
4
4
|
const { HOSTS } = require('../mcp/hosts');
|
|
5
5
|
const { getPackageVersion } = require('../skill');
|
|
6
6
|
|
|
@@ -13,8 +13,8 @@ function help() {
|
|
|
13
13
|
|
|
14
14
|
console.log(`draftgo v${getPackageVersion()} - DraftGo workbench CLI for AI coding agents
|
|
15
15
|
|
|
16
|
-
DraftGo
|
|
17
|
-
|
|
16
|
+
DraftGo shell baseline: React + Vite. Database Pages default to native HTML,
|
|
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.
|
|
@@ -26,9 +26,9 @@ Usage:
|
|
|
26
26
|
refresh installed or detected Skills.
|
|
27
27
|
draftgo uninstall <target|all> Remove Skill files. --purge also removes
|
|
28
28
|
the entire .draftgo/ runtime directory.
|
|
29
|
-
draftgo status Show
|
|
29
|
+
draftgo status Show connection health, current scope, targets, and Skill version.
|
|
30
30
|
|
|
31
|
-
draftgo connect [<target>...] Verify and save server/
|
|
31
|
+
draftgo connect [<target>...] Verify and save server/API Key, then configure
|
|
32
32
|
a detected or explicit MCP host. This never
|
|
33
33
|
downloads DraftGo business resources.
|
|
34
34
|
draftgo mcp setup [<target>...] Merge project-level stdio MCP configuration.
|
|
@@ -36,24 +36,42 @@ Usage:
|
|
|
36
36
|
draftgo mcp test Test project, resource, and API MCP calls.
|
|
37
37
|
draftgo mcp serve Bridge local stdio to the remote /mcp endpoint.
|
|
38
38
|
|
|
39
|
-
draftgo map
|
|
40
|
-
overlay local checkout state.
|
|
41
|
-
|
|
39
|
+
draftgo map [--type <type>] Locate bounded remote resource metadata and
|
|
40
|
+
overlay matching local checkout state.
|
|
41
|
+
Use --route/--title for exact selection.
|
|
42
|
+
draftgo checkout <type> <id...> Download a long-form body + verified base,
|
|
43
|
+
including custom-service worktrees.
|
|
42
44
|
--force explicitly replaces local changes.
|
|
43
45
|
draftgo check [custom-services <id...>]
|
|
44
46
|
Validate all checkouts or selected custom services.
|
|
45
47
|
--remote also compares remote hash/version.
|
|
46
|
-
draftgo verify [<type> <id...>] Run
|
|
47
|
-
|
|
48
|
-
draftgo diff <type> <id> Show checkout base versus local body.
|
|
49
|
-
|
|
48
|
+
draftgo verify [<type> <id...>] Run the default delivery verification.
|
|
49
|
+
Browser options are explicit and optional.
|
|
50
|
+
draftgo diff <type> <id> Show checkout base versus local body/files.
|
|
51
|
+
--stat/--summary omit the full patch.
|
|
52
|
+
draftgo commit <type> <id...> Validate and upload complete checked-out bodies/files.
|
|
53
|
+
draftgo components search <query> Search the live component catalog.
|
|
54
|
+
draftgo components show <library/component>
|
|
55
|
+
Show HTML, props, slots, CSS variables and revision.
|
|
56
|
+
draftgo components expand --page <id> --instance <data-dg-instance>
|
|
57
|
+
Expand one component in a checked-out Page worktree.
|
|
58
|
+
draftgo components libraries list|show|create|update|delete
|
|
59
|
+
Manage component libraries.
|
|
60
|
+
draftgo components list|create|copy|delete
|
|
61
|
+
Manage component catalog entries.
|
|
62
|
+
draftgo components checkout|diff|verify|commit|publish <library/component>
|
|
63
|
+
Develop a component draft locally, then publish explicitly.
|
|
64
|
+
draftgo components import <zip> [--dry-run]
|
|
65
|
+
draftgo components export <library> [--file <zip>]
|
|
66
|
+
Transfer standard DraftGo component archives.
|
|
50
67
|
draftgo refresh <type> <id...> Safely refresh a clean checkout from the cloud.
|
|
51
68
|
draftgo validate custom-services <id>
|
|
52
69
|
Build and inspect the current cloud draft.
|
|
53
|
-
draftgo test custom-services <id> [--handler <selector>]
|
|
70
|
+
draftgo test custom-services <id> [--source <source>] [--input <file>] [--handler <selector>]
|
|
54
71
|
Run the cloud draft in the DraftGo Runner.
|
|
55
72
|
draftgo publish custom-services <id...>
|
|
56
|
-
Publish validated drafts
|
|
73
|
+
Publish current validated drafts; batch errors
|
|
74
|
+
report services already completed.
|
|
57
75
|
draftgo reconcile <type> <id...> Repair stale metadata only when local equals remote.
|
|
58
76
|
draftgo conflicts List unresolved conflicts; --all includes resolved.
|
|
59
77
|
draftgo conflict show <type> <id>
|
|
@@ -61,37 +79,40 @@ Usage:
|
|
|
61
79
|
draftgo conflict resolve <type> <id>
|
|
62
80
|
Mark a merged worktree file ready against the
|
|
63
81
|
preserved remote base; then check/diff/commit.
|
|
64
|
-
draftgo verify-ui <url> Deprecated alias for verify --url <url> --ui always.
|
|
65
82
|
draftgo clean [--dry-run|--yes] Plan or remove all tmp and registered artifacts.
|
|
66
|
-
draftgo
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
83
|
+
draftgo work start <item> Add an active item to .draftgo/worklog.md.
|
|
84
|
+
draftgo work add <item> Add a pending item.
|
|
85
|
+
draftgo work start-item <ref> Mark an item active; ref is number or date#number.
|
|
86
|
+
draftgo work complete <ref> Mark an item complete; --note appends evidence.
|
|
87
|
+
draftgo work show|list Show the worklog or its structured item list.
|
|
70
88
|
|
|
71
89
|
draftgo api <query> Search the live API contract through MCP.
|
|
72
90
|
draftgo api describe <operation_id>
|
|
73
91
|
Describe one live API operation through MCP.
|
|
74
92
|
draftgo api call <operation_id> --input <json-file>
|
|
75
93
|
Call one described operation with UTF-8 JSON.
|
|
94
|
+
draftgo capabilities list|search|show|audit
|
|
95
|
+
Discover and audit the current server's live operation catalog.
|
|
96
|
+
draftgo space <action> Manage spaces and workspace members.
|
|
97
|
+
draftgo group <action> Manage workspace groups and group members.
|
|
98
|
+
draftgo grant list|create|get|revoke
|
|
99
|
+
Manage platform/space AccessGrants.
|
|
100
|
+
draftgo api-key status|create|update|delete|rotate|reset|enable|disable
|
|
101
|
+
Manage the current user's API key through MCP.
|
|
102
|
+
draftgo role permissions|list|create|get|update|delete
|
|
103
|
+
Manage structured permission templates.
|
|
104
|
+
draftgo data-range list|create|get|update|batch|delete
|
|
105
|
+
Manage db_meta record policies (none|owner|all).
|
|
76
106
|
draftgo delete <operation_id> [id]
|
|
77
107
|
Confirm and call a live delete operation.
|
|
78
|
-
Legacy <type> <id> works only when unambiguous.
|
|
79
108
|
draftgo deploy [<type> <id...>] Check, then diff or commit checked-out content.
|
|
80
109
|
--delivery local needs no IDs; preview/deploy
|
|
81
110
|
require an explicit type and IDs.
|
|
82
111
|
draftgo auto-push [<type> <id...>]
|
|
83
112
|
With config.auto_push=true, check and commit
|
|
84
113
|
changed checkouts. Any conflict stops the run.
|
|
85
|
-
draftgo changelog add <result> Append one completed result after the task has
|
|
86
|
-
passed unified verification and delivery.
|
|
87
|
-
draftgo pull Migration notice only; always downloads nothing.
|
|
88
|
-
draftgo push <type> <id...> Deprecated alias to commit for pages/nav/docs.
|
|
89
|
-
Push-all and structured-resource push are removed.
|
|
90
|
-
|
|
91
114
|
draftgo local setup|start|stop|logs|status
|
|
92
|
-
Manage the
|
|
93
|
-
remain aliases for start/stop; status also has ps.
|
|
94
|
-
draftgo local-dev Compatibility alias for \`draftgo local setup\`.
|
|
115
|
+
Manage the project-local Docker stack.
|
|
95
116
|
draftgo list-targets List Skill installation targets.
|
|
96
117
|
draftgo -v | --version Print CLI version.
|
|
97
118
|
draftgo -h | --help Show this help.
|
|
@@ -105,7 +126,9 @@ Important flags:
|
|
|
105
126
|
--server <url> (connect) DraftGo base URL.
|
|
106
127
|
--mcp-url <url> (connect) Explicit endpoint; standard /mcp derives the
|
|
107
128
|
base URL; custom paths also need --server.
|
|
108
|
-
--
|
|
129
|
+
--api-key <key> (connect) DraftGo user API Key for non-interactive use.
|
|
130
|
+
--scope-type space --space-id <id>
|
|
131
|
+
(connect) Save a target space for workspace resources.
|
|
109
132
|
--timeout <ms> (connect/mcp test) Network timeout.
|
|
110
133
|
--allow-offline (connect) Save only after explicitly accepting a
|
|
111
134
|
failed MCP validation.
|
|
@@ -114,42 +137,49 @@ Important flags:
|
|
|
114
137
|
--purge (uninstall) Also remove the .draftgo/ directory.
|
|
115
138
|
--skip-update-check (update) Refresh Skills without contacting npm.
|
|
116
139
|
--connect (init) Continue into DraftGo server connection.
|
|
117
|
-
--local-dev (init) Continue into local Docker setup.
|
|
118
140
|
--no-setup (init) Install the Skill without either setup flow.
|
|
119
141
|
--output json Print machine-readable output where supported.
|
|
120
|
-
--type <type> (map) pages | nav/navigations | docs/articles
|
|
142
|
+
--type <type> (map) pages | nav/navigations | docs/articles |
|
|
143
|
+
custom-services.
|
|
144
|
+
--route <path> (map) Select resources with this exact route.
|
|
145
|
+
--title <title> (map) Select resources with this exact title.
|
|
146
|
+
--limit <1-100> (map) Maximum resources returned per type/page;
|
|
147
|
+
defaults to 20.
|
|
148
|
+
--cursor <cursor> (map) Continue one typed map result page.
|
|
149
|
+
--summary (map/diff) Print bounded resource or change summary.
|
|
150
|
+
--stat (diff) Print per-file and total change statistics.
|
|
121
151
|
--strict Treat check warnings as failures.
|
|
122
152
|
--remote (check) Compare checkout hashes/versions with remote.
|
|
123
153
|
--yes Skip supported confirmation prompts.
|
|
124
154
|
--operation-id <id> (delete) Select an operation explicitly.
|
|
125
155
|
--params <json> (api call/delete) Pass an API parameter object.
|
|
126
|
-
--input <file> (api call/delete) Read a UTF-8
|
|
156
|
+
--input <file> (api call/delete/custom-service test) Read a UTF-8
|
|
157
|
+
JSON object.
|
|
127
158
|
--handler <selector> (custom-service test) route:METHOD:/path, event:name,
|
|
128
159
|
scheduled:name, or a handler name.
|
|
160
|
+
--source <source> (custom-service test) draft (default), auto, or published.
|
|
129
161
|
--headers/--user <file> (custom-service test) Read JSON test identity data.
|
|
130
162
|
--test-write (custom-service test) Permit declared write testing.
|
|
131
163
|
--side-effect-policy <mode>
|
|
132
164
|
(custom-service test) deny | mock | live; default deny.
|
|
133
165
|
--delivery <mode> (deploy) local | preview | deploy.
|
|
134
|
-
--dry-run
|
|
135
|
-
--ui <mode> (verify)
|
|
166
|
+
--dry-run Preview supported cleanup or delivery operations.
|
|
167
|
+
--ui <mode> (verify) always | never; default never.
|
|
136
168
|
--remote (check/verify) Compare checkout hashes with remote.
|
|
137
169
|
--viewport <mode> (verify) mobile | desktop | both.
|
|
138
170
|
--frame <mode> (verify) auto | top | all | <iframe-selector>.
|
|
139
|
-
--mobile-check <mode> (verify-ui compatibility) auto | always | never.
|
|
140
171
|
--token <mode> (verify) auto | never; auto appends the configured
|
|
141
|
-
|
|
142
|
-
--screenshot <mode> (verify)
|
|
172
|
+
API Key to same-origin URLs as the token query parameter.
|
|
173
|
+
--screenshot <mode> (verify) always | never; always alone captures a screenshot.
|
|
143
174
|
--browser <name> (verify) chromium | chrome | msedge.
|
|
144
175
|
--browser-path <file> (verify) Explicit browser executable; environment
|
|
145
176
|
fallback: DRAFTGO_BROWSER_PATH.
|
|
146
|
-
--resource <type:id> (verify compatibility) Assert one remote UI resource.
|
|
147
177
|
--selector <css> (verify) Require a visible element in top or iframe DOM.
|
|
148
|
-
--width/--height <px> (verify) Override the default
|
|
178
|
+
--width/--height <px> (verify) Override the default 1440x900 desktop viewport.
|
|
149
179
|
|
|
150
180
|
Security:
|
|
151
|
-
.draftgo/config.json stores the server and
|
|
152
|
-
files contain only "draftgo mcp serve"; they never contain the
|
|
181
|
+
.draftgo/config.json stores the server and API Key and is gitignored. Host MCP
|
|
182
|
+
files contain only "draftgo mcp serve"; they never contain the API Key.
|
|
153
183
|
|
|
154
184
|
MCP targets (project config or status):
|
|
155
185
|
${mcpTargets}
|
|
@@ -159,18 +189,17 @@ ${targets}
|
|
|
159
189
|
|
|
160
190
|
Examples:
|
|
161
191
|
draftgo init codex
|
|
162
|
-
draftgo connect codex --server https://draftgo.example --
|
|
192
|
+
draftgo connect codex --server https://draftgo.example --api-key <key>
|
|
163
193
|
draftgo mcp test
|
|
164
|
-
draftgo map --output json
|
|
194
|
+
draftgo map --type pages --route /admin/channel-ops --summary --output json
|
|
165
195
|
draftgo checkout pages 42
|
|
166
|
-
draftgo
|
|
167
|
-
draftgo
|
|
168
|
-
draftgo diff pages 42
|
|
196
|
+
draftgo verify pages 42
|
|
197
|
+
draftgo diff pages 42 --stat
|
|
169
198
|
draftgo commit pages 42
|
|
170
|
-
draftgo
|
|
171
|
-
draftgo
|
|
172
|
-
|
|
173
|
-
|
|
199
|
+
draftgo checkout custom-services 12
|
|
200
|
+
draftgo test custom-services 12 --handler route:POST:/health --input request.json
|
|
201
|
+
draftgo work start "Build document management and role permissions"
|
|
202
|
+
draftgo work complete 1 --note "Verification and delivery passed"
|
|
174
203
|
draftgo deploy docs 7 --delivery preview
|
|
175
204
|
`);
|
|
176
205
|
}
|
package/src/commands/init.js
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
const path = require('path');
|
|
4
4
|
const log = require('../logger');
|
|
5
5
|
const { detectTargets } = require('../detect');
|
|
6
|
-
const { resolveTargets, all } = require('../
|
|
6
|
+
const { resolveTargets, all } = require('../targets');
|
|
7
7
|
const { ensureRuntime, getPackageVersion } = require('../skill');
|
|
8
8
|
const { exists } = require('../fsx');
|
|
9
9
|
const { ask } = require('../prompt');
|
|
@@ -76,29 +76,23 @@ async function init(projectDir, positional, flags) {
|
|
|
76
76
|
const cfgPath = path.join(projectDir, '.draftgo', 'config.json');
|
|
77
77
|
const hasConfig = exists(cfgPath);
|
|
78
78
|
const flagConnect = flags.connect === true;
|
|
79
|
-
const
|
|
80
|
-
const flagSkip = flags['no-local-dev'] === true
|
|
81
|
-
|| flags['skip-local-dev'] === true
|
|
82
|
-
|| flags['no-setup'] === true;
|
|
79
|
+
const flagSkip = flags['no-setup'] === true;
|
|
83
80
|
const interactive = process.stdin.isTTY && process.stdout.isTTY;
|
|
84
81
|
|
|
85
82
|
if (!hasConfig && !flagSkip) {
|
|
86
|
-
//
|
|
87
|
-
if (flags.server && flags.token && !flagConnect
|
|
83
|
+
// Non-interactive setup can connect immediately with a server and API Key.
|
|
84
|
+
if (flags.server && (flags['api-key'] || flags.token) && !flagConnect) {
|
|
88
85
|
return await require('./connect')(projectDir, [], flags);
|
|
89
86
|
}
|
|
90
87
|
if (flagConnect) {
|
|
91
88
|
return await require('./connect')(projectDir, [], flags);
|
|
92
89
|
}
|
|
93
|
-
if (flagLocalDev) {
|
|
94
|
-
return await require('./localDev')(projectDir, [], flags);
|
|
95
|
-
}
|
|
96
90
|
if (interactive) {
|
|
97
91
|
log.title('选择 DraftGo 基座处理方式');
|
|
98
92
|
log.plain(` ${log.c.cyan('[A]')} 连接基座服务`);
|
|
99
93
|
log.dim(' 使用已有 DraftGo 服务,接下来输入 BaseURL 和系统访问令牌。');
|
|
100
94
|
log.plain(` ${log.c.cyan('[B]')} 本地启动基座`);
|
|
101
|
-
log.dim(' 使用 Docker 启动 DraftGo;按需准备共享的 MySQL、Redis 和
|
|
95
|
+
log.dim(' 使用 Docker 启动 DraftGo;按需准备共享的 MySQL、Redis 和 Qdrant。');
|
|
102
96
|
log.plain(` ${log.c.cyan('[C]')} 稍后自行处理`);
|
|
103
97
|
log.dim(' 仅安装 Skill,不写入服务配置,也不创建容器。');
|
|
104
98
|
const choice = (await ask('请选择 [A/B/C]', { default: 'C' })).trim().toUpperCase();
|
|
@@ -106,7 +100,7 @@ async function init(projectDir, positional, flags) {
|
|
|
106
100
|
return await require('./connect')(projectDir, [], flags);
|
|
107
101
|
}
|
|
108
102
|
if (choice === 'B') {
|
|
109
|
-
return await require('
|
|
103
|
+
return await require('../localRuntime').runWizard(projectDir, { yes: true });
|
|
110
104
|
}
|
|
111
105
|
if (choice !== 'C') {
|
|
112
106
|
log.warn('无效选择,已跳过基座处理。');
|