draftgo-cli 4.0.24 → 4.0.26
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 +23 -37
- package/package.json +3 -5
- package/resources/skill/SKILL.md +9 -5
- package/resources/skill/manifest.json +2 -5
- package/resources/skill/references/ai.md +41 -0
- package/resources/skill/references/app-api.md +2 -50
- package/resources/skill/references/architecture.md +1 -1
- package/resources/skill/references/chat-sdk.md +29 -37
- package/resources/skill/references/checkout.md +4 -4
- package/resources/skill/references/data.md +0 -46
- package/resources/skill/references/delivery.md +3 -3
- package/resources/skill/references/diagnostics.md +10 -11
- package/resources/skill/references/frontend.md +23 -20
- package/resources/skill/references/mcp.md +4 -14
- package/resources/skill/references/methods.md +15 -68
- package/resources/skill/references/modules.md +23 -44
- package/resources/skill/references/runtime.md +3 -20
- package/resources/skill/story/SKILL.md +2 -2
- package/src/apiContractCache.js +14 -6
- package/src/cli.js +0 -7
- package/src/commandRegistry.js +0 -6
- package/src/commands/api.js +87 -17
- package/src/commands/apiKey.js +2 -6
- package/src/commands/autoPush.js +15 -51
- package/src/commands/capabilities.js +22 -15
- package/src/commands/check.js +19 -53
- package/src/commands/checkout.js +1 -4
- package/src/commands/clean.js +1 -1
- package/src/commands/commit.js +1 -4
- package/src/commands/components.js +12 -8
- package/src/commands/conflict.js +4 -6
- package/src/commands/conflicts.js +1 -2
- package/src/commands/connect.js +0 -8
- package/src/commands/delete.js +15 -11
- package/src/commands/deploy.js +64 -26
- package/src/commands/diff.js +1 -4
- package/src/commands/group.js +2 -3
- package/src/commands/help.js +22 -43
- package/src/commands/init.js +13 -6
- package/src/commands/local.js +4 -1
- package/src/commands/map.js +138 -23
- package/src/commands/reconcile.js +1 -15
- package/src/commands/role.js +1 -2
- package/src/commands/status.js +12 -40
- package/src/commands/update.js +18 -24
- package/src/commands/verify.js +8 -7
- package/src/commands/worklog.js +11 -5
- package/src/contractCompatibility.js +10 -2
- package/src/localRuntime/compose.js +41 -27
- package/src/localRuntime/detect.js +6 -6
- package/src/localRuntime/index.js +47 -47
- package/src/localRuntime/services.js +2 -39
- package/src/mcp/client.js +99 -134
- package/src/mcp/parallel.js +25 -2
- package/src/mcp/protocol.js +38 -9
- package/src/mcp/tools.js +10 -19
- package/src/projectConfig.js +1 -4
- package/src/{workspaceHealth.js → projectHealth.js} +5 -5
- package/src/projectMap.js +1 -1
- package/src/runtimeFiles.js +2 -1
- package/src/worklog.js +3 -2
- package/src/worktree/backend.js +127 -15
- package/src/worktree/index.js +64 -22
- package/src/worktree/locks.js +52 -0
- package/src/worktree/manifest.js +18 -4
- package/src/worktree/status.js +4 -2
- package/resources/custom-service-sdk/ai.go +0 -520
- package/resources/custom-service-sdk/ai_test.go +0 -156
- package/resources/custom-service-sdk/auth_test.go +0 -56
- package/resources/custom-service-sdk/billing.go +0 -596
- package/resources/custom-service-sdk/billing_test.go +0 -150
- package/resources/custom-service-sdk/go.mod +0 -3
- package/resources/custom-service-sdk/manifest.json +0 -77
- package/resources/custom-service-sdk/platform.go +0 -352
- package/resources/custom-service-sdk/platform_logger_test.go +0 -24
- package/resources/custom-service-sdk/registration_test.go +0 -39
- package/resources/custom-service-sdk/resources.go +0 -247
- package/resources/custom-service-sdk/resources_billing_test.go +0 -115
- package/resources/custom-service-sdk/resources_files_test.go +0 -57
- package/resources/custom-service-sdk/resources_scope_test.go +0 -92
- package/resources/custom-service-sdk/sdk.go +0 -209
- package/resources/skill/references/aihub.md +0 -116
- package/resources/skill/references/custom-services.md +0 -201
- package/src/commands/customService.js +0 -95
- package/src/commands/dataRange.js +0 -33
- package/src/commands/grant.js +0 -29
- package/src/commands/space.js +0 -41
- package/src/customServices.js +0 -484
|
@@ -46,7 +46,7 @@ function csv(value) {
|
|
|
46
46
|
|
|
47
47
|
function normalizeDefinition(definition = {}) {
|
|
48
48
|
return {
|
|
49
|
-
html: definition.html || '', css: definition.css || '', js: definition.js || '',
|
|
49
|
+
html: definition.html || '', css: definition.css || '', js: definition.js || '', assets: definition.assets || [],
|
|
50
50
|
props: definition.props || [], slots: definition.slots || [], css_variables: definition.css_variables || [],
|
|
51
51
|
events: definition.events || [], dependencies: definition.dependencies || [], examples: definition.examples || [],
|
|
52
52
|
usage: definition.usage || '', root_tag: definition.root_tag || '', meta: definition.meta || {},
|
|
@@ -66,12 +66,12 @@ function componentDir(projectDir, name) {
|
|
|
66
66
|
}
|
|
67
67
|
|
|
68
68
|
function contractFrom(definition = {}) {
|
|
69
|
-
const { props, slots, css_variables, events, dependencies, examples, usage, root_tag, meta } = normalizeDefinition(definition);
|
|
70
|
-
return { props, slots, css_variables, events, dependencies, examples, usage, root_tag, meta };
|
|
69
|
+
const { assets, props, slots, css_variables, events, dependencies, examples, usage, root_tag, meta } = normalizeDefinition(definition);
|
|
70
|
+
return { assets, props, slots, css_variables, events, dependencies, examples, usage, root_tag, meta };
|
|
71
71
|
}
|
|
72
72
|
|
|
73
73
|
function localDefinition(directory) {
|
|
74
|
-
const contract = JSON.parse(fs.readFileSync(path.join(directory, '
|
|
74
|
+
const contract = JSON.parse(fs.readFileSync(path.join(directory, 'component.json'), 'utf8'));
|
|
75
75
|
return normalizeDefinition({
|
|
76
76
|
html: fs.readFileSync(path.join(directory, 'component.html'), 'utf8'),
|
|
77
77
|
css: fs.readFileSync(path.join(directory, 'component.css'), 'utf8'),
|
|
@@ -85,12 +85,12 @@ function writeComponentFiles(directory, item) {
|
|
|
85
85
|
fs.writeFileSync(path.join(directory, 'component.html'), item.draft.html || '', 'utf8');
|
|
86
86
|
fs.writeFileSync(path.join(directory, 'component.css'), item.draft.css || '', 'utf8');
|
|
87
87
|
fs.writeFileSync(path.join(directory, 'component.js'), item.draft.js || '', 'utf8');
|
|
88
|
-
fs.writeFileSync(path.join(directory, 'contract.json'), `${JSON.stringify(contractFrom(item.draft), null, 2)}\n`, 'utf8');
|
|
89
88
|
const metadata = {
|
|
90
89
|
id: item.id, library_id: item.library_id, library_slug: item.library_slug,
|
|
91
90
|
name: item.name, slug: item.slug, category: item.category || '', description: item.description || '',
|
|
92
91
|
tags: item.tags || [], status: item.status || 'active', published_revision: item.published_revision || 0,
|
|
93
92
|
remote_draft_hash: definitionHash(item.draft), updated_at: item.updated_at,
|
|
93
|
+
...contractFrom(item.draft),
|
|
94
94
|
};
|
|
95
95
|
fs.writeFileSync(path.join(directory, 'component.json'), `${JSON.stringify(metadata, null, 2)}\n`, 'utf8');
|
|
96
96
|
fs.writeFileSync(path.join(directory, '.base.json'), `${JSON.stringify(item, null, 2)}\n`, 'utf8');
|
|
@@ -231,7 +231,7 @@ async function diff(projectDir, name, flags) {
|
|
|
231
231
|
const config = loadProjectConfig(projectDir);
|
|
232
232
|
const state = localState(projectDir, name);
|
|
233
233
|
const remote = await findComponent(config, name);
|
|
234
|
-
const sections = ['html', 'css', 'js', 'props', 'slots', 'css_variables', 'events', 'dependencies', 'examples', 'usage', 'root_tag', 'meta'];
|
|
234
|
+
const sections = ['html', 'css', 'js', 'assets', 'props', 'slots', 'css_variables', 'events', 'dependencies', 'examples', 'usage', 'root_tag', 'meta'];
|
|
235
235
|
const changed = (left, right) => {
|
|
236
236
|
const normalizedLeft = normalizeDefinition(left);
|
|
237
237
|
const normalizedRight = normalizeDefinition(right);
|
|
@@ -364,9 +364,13 @@ async function exportZIP(projectDir, librarySlug, flags) {
|
|
|
364
364
|
}
|
|
365
365
|
for (const summary of components) {
|
|
366
366
|
const item = await request(config, 'GET', `components/${summary.id}`);
|
|
367
|
-
const
|
|
367
|
+
const directory = `components/${item.slug}`;
|
|
368
|
+
const definition = `${directory}/component.json`;
|
|
368
369
|
manifest.components.push({ name: item.name, slug: item.slug, category: item.category, description: item.description, tags: item.tags, definition });
|
|
369
|
-
zip.addFile(definition, Buffer.from(`${JSON.stringify(item.draft, null, 2)}\n`, 'utf8'));
|
|
370
|
+
zip.addFile(definition, Buffer.from(`${JSON.stringify(contractFrom(item.draft), null, 2)}\n`, 'utf8'));
|
|
371
|
+
zip.addFile(`${directory}/component.html`, Buffer.from(item.draft.html || '', 'utf8'));
|
|
372
|
+
zip.addFile(`${directory}/component.css`, Buffer.from(item.draft.css || '', 'utf8'));
|
|
373
|
+
zip.addFile(`${directory}/component.js`, Buffer.from(item.draft.js || '', 'utf8'));
|
|
370
374
|
}
|
|
371
375
|
zip.addFile('draftgo-components.json', Buffer.from(`${JSON.stringify(manifest, null, 2)}\n`, 'utf8'));
|
|
372
376
|
const destination = path.resolve(projectDir, flags.file || `${library.slug}-components.zip`);
|
package/src/commands/conflict.js
CHANGED
|
@@ -15,14 +15,12 @@ function printRecord(record) {
|
|
|
15
15
|
async function conflict(projectDir, positional, flags = {}) {
|
|
16
16
|
const [action, resourceType, resourceId] = positional;
|
|
17
17
|
if (!['show', 'resolve'].includes(action) || !resourceType || !resourceId) {
|
|
18
|
-
log.err('Usage: draftgo conflict <show|resolve> <pages|nav|docs
|
|
18
|
+
log.err('Usage: draftgo conflict <show|resolve> <pages|nav|docs> <id>');
|
|
19
19
|
return 1;
|
|
20
20
|
}
|
|
21
|
-
const
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
? (action === 'show' ? services.showConflict(projectDir, resourceId) : services.resolveConflict(projectDir, resourceId))
|
|
25
|
-
: (action === 'show' ? showConflict(projectDir, resourceType, resourceId) : await resolveConflict(projectDir, resourceType, resourceId));
|
|
21
|
+
const record = action === 'show'
|
|
22
|
+
? showConflict(projectDir, resourceType, resourceId)
|
|
23
|
+
: await resolveConflict(projectDir, resourceType, resourceId);
|
|
26
24
|
if (flags.output === 'json') console.log(JSON.stringify(record, null, 2));
|
|
27
25
|
else printRecord(record);
|
|
28
26
|
if (action === 'resolve') log.info('The remote revision is now the base; run check, diff, and commit the merged worktree file.');
|
|
@@ -2,10 +2,9 @@
|
|
|
2
2
|
|
|
3
3
|
const log = require('../logger');
|
|
4
4
|
const { listConflicts } = require('../worktree');
|
|
5
|
-
const { serviceConflicts } = require('../customServices');
|
|
6
5
|
|
|
7
6
|
function conflicts(projectDir, _positional, flags = {}) {
|
|
8
|
-
const records =
|
|
7
|
+
const records = listConflicts(projectDir, { all: Boolean(flags.all) });
|
|
9
8
|
if (flags.output === 'json') console.log(JSON.stringify(records, null, 2));
|
|
10
9
|
else if (!records.length) log.ok('No unresolved DraftGo conflicts.');
|
|
11
10
|
else for (const record of records) {
|
package/src/commands/connect.js
CHANGED
|
@@ -49,16 +49,10 @@ async function connect(projectDir, positional, flags = {}) {
|
|
|
49
49
|
return 1;
|
|
50
50
|
}
|
|
51
51
|
const timeoutMs = parseTimeout(flags.timeout);
|
|
52
|
-
if ((flags['scope-type'] === 'space') !== Boolean(flags['space-id'])) {
|
|
53
|
-
throw new Error('--scope-type space and --space-id must be provided together.');
|
|
54
|
-
}
|
|
55
|
-
|
|
56
52
|
log.step('Validating DraftGo API Key and MCP capabilities...');
|
|
57
53
|
try {
|
|
58
54
|
const diagnostic = await testConnection({ ...connection, server, token }, {
|
|
59
55
|
timeoutMs,
|
|
60
|
-
scopeType: flags['scope-type'],
|
|
61
|
-
spaceId: flags['space-id'] && Number(flags['space-id']),
|
|
62
56
|
});
|
|
63
57
|
log.ok(`MCP ready (${diagnostic.tools.length} tools; tested ${diagnostic.testedCalls.join(', ')}).`);
|
|
64
58
|
} catch (error) {
|
|
@@ -74,8 +68,6 @@ async function connect(projectDir, positional, flags = {}) {
|
|
|
74
68
|
|
|
75
69
|
const configFile = writeProjectConfig(projectDir, server, token, {
|
|
76
70
|
mcp_url: connection.mcp_url,
|
|
77
|
-
scope_type: flags['scope-type'],
|
|
78
|
-
space_id: flags['space-id'],
|
|
79
71
|
});
|
|
80
72
|
log.ok(`Project configuration written: ${configFile}`);
|
|
81
73
|
|
package/src/commands/delete.js
CHANGED
|
@@ -6,7 +6,8 @@ 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
|
-
const { cachedDescription
|
|
9
|
+
const { cachedDescription } = require('../apiContractCache');
|
|
10
|
+
const { registryRevision, describeOperation } = require('./api');
|
|
10
11
|
const {
|
|
11
12
|
isContractCompatibilityError,
|
|
12
13
|
isHardContractIncompatibility,
|
|
@@ -26,10 +27,14 @@ function readParams(projectDir, flags) {
|
|
|
26
27
|
}
|
|
27
28
|
|
|
28
29
|
function pathParameterName(description) {
|
|
29
|
-
const
|
|
30
|
-
|
|
31
|
-
const
|
|
32
|
-
|
|
30
|
+
const operation = description && (description.operation || description) || {};
|
|
31
|
+
const properties = operation.input_schema && operation.input_schema.properties || {};
|
|
32
|
+
const pathProperties = properties.path && properties.path.properties || {};
|
|
33
|
+
const names = Object.keys(pathProperties);
|
|
34
|
+
if (names.length === 1) return names[0];
|
|
35
|
+
const parameters = operation.parameters || operation.params || [];
|
|
36
|
+
const legacy = parameters.filter((parameter) => parameter && parameter.in === 'path');
|
|
37
|
+
return legacy.length === 1 ? legacy[0].name : null;
|
|
33
38
|
}
|
|
34
39
|
|
|
35
40
|
async function deleteResource(projectDir, positional, flags = {}) {
|
|
@@ -39,7 +44,7 @@ async function deleteResource(projectDir, positional, flags = {}) {
|
|
|
39
44
|
}
|
|
40
45
|
const config = loadProjectConfig(projectDir);
|
|
41
46
|
const session = await openToolSession(config, [
|
|
42
|
-
TOOL_NAMES.apiDescribe, TOOL_NAMES.apiCall,
|
|
47
|
+
TOOL_NAMES.apiSearch, TOOL_NAMES.apiDescribe, TOOL_NAMES.apiCall,
|
|
43
48
|
]);
|
|
44
49
|
|
|
45
50
|
const selectedOperation = flags['operation-id'] ? String(flags['operation-id']) : String(positional[0]);
|
|
@@ -47,8 +52,7 @@ async function deleteResource(projectDir, positional, flags = {}) {
|
|
|
47
52
|
|
|
48
53
|
let contract = cachedDescription(projectDir, config.server, selectedOperation);
|
|
49
54
|
if (!contract) {
|
|
50
|
-
|
|
51
|
-
contract = storeDescription(projectDir, config.server, described) || normalizeDescription(described);
|
|
55
|
+
contract = await describeOperation(projectDir, config, session, selectedOperation);
|
|
52
56
|
}
|
|
53
57
|
if (!contract) throw new Error('DraftGo API description is missing contract revision metadata.');
|
|
54
58
|
const params = readParams(projectDir, flags);
|
|
@@ -58,7 +62,7 @@ async function deleteResource(projectDir, positional, flags = {}) {
|
|
|
58
62
|
log.err('The operation does not expose exactly one path parameter; provide --params JSON explicitly.');
|
|
59
63
|
return 1;
|
|
60
64
|
}
|
|
61
|
-
params.
|
|
65
|
+
params.path = { [parameterName]: resourceId };
|
|
62
66
|
}
|
|
63
67
|
if (!flags.yes && !flags.y) {
|
|
64
68
|
const approved = await confirm(`Call destructive DraftGo operation ${selectedOperation}?`, { default: false });
|
|
@@ -74,8 +78,8 @@ async function deleteResource(projectDir, positional, flags = {}) {
|
|
|
74
78
|
if (!isContractCompatibilityError(error)) throw error;
|
|
75
79
|
if (isHardContractIncompatibility(error)) throw incompatibleOperationError(selectedOperation, error);
|
|
76
80
|
const previousContract = contract;
|
|
77
|
-
const
|
|
78
|
-
contract =
|
|
81
|
+
const revision = await registryRevision(session, selectedOperation);
|
|
82
|
+
contract = await describeOperation(projectDir, config, session, selectedOperation, revision);
|
|
79
83
|
if (!contract) throw new Error('DraftGo API description is missing contract revision metadata.');
|
|
80
84
|
if (!sameOperationContract(previousContract, contract)) {
|
|
81
85
|
throw incompatibleOperationError(selectedOperation, error);
|
package/src/commands/deploy.js
CHANGED
|
@@ -2,38 +2,76 @@
|
|
|
2
2
|
|
|
3
3
|
const log = require('../logger');
|
|
4
4
|
const check = require('./check');
|
|
5
|
+
const { canonicalResourceType, entryKey } = require('../worktree/types');
|
|
6
|
+
const { commitBatch, diffResource } = require('../worktree');
|
|
7
|
+
const { report, formatSummary, formatStat } = require('../diffReport');
|
|
8
|
+
const { absolutePath } = require('../worktree/manifest');
|
|
5
9
|
|
|
6
|
-
|
|
7
|
-
const
|
|
8
|
-
if (!
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
10
|
+
function targetsFrom(positional) {
|
|
11
|
+
const [type, ...ids] = positional;
|
|
12
|
+
if (!type || !ids.length) throw new Error('Specify <pages|nav|docs> <id...>.');
|
|
13
|
+
const resource_type = canonicalResourceType(type);
|
|
14
|
+
return [...new Set(ids.map(String))].map((resource_id) => ({ resource_type, resource_id }));
|
|
15
|
+
}
|
|
12
16
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
if (
|
|
16
|
-
log.err(
|
|
17
|
-
|
|
17
|
+
function outputResult(value, flags) {
|
|
18
|
+
if (flags.output === 'json') console.log(JSON.stringify(value, null, 2));
|
|
19
|
+
else if (value.error) {
|
|
20
|
+
log.err(value.error.message);
|
|
21
|
+
for (const message of value.validation?.content_validation?.errors || []) log.err(message);
|
|
22
|
+
if (value.completed?.length) log.warn('Completed resources already changed remotely; use draftgo check --remote before retrying.');
|
|
23
|
+
} else if (value.skipped) log.dim(value.skipped);
|
|
24
|
+
else log.ok(`${value.delivery}: ${value.completed?.length || 0} resource(s) completed.`);
|
|
25
|
+
return value.error ? 1 : 0;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
async function deliverTargets(projectDir, targets, flags = {}, options = {}) {
|
|
29
|
+
const delivery = flags.delivery || 'deploy';
|
|
30
|
+
const validation = await check(projectDir, { strict: flags.strict, quiet: true, returnResult: true,
|
|
31
|
+
resourceKeys: targets?.map((item) => entryKey(item.resource_type, item.resource_id)) });
|
|
32
|
+
if (validation.code) return { delivery, validation, error: { code: 'VALIDATION_FAILED', message: 'Delivery stopped because local validation failed.' },
|
|
33
|
+
completed: [], failed: [], not_started: targets || [] };
|
|
34
|
+
if (delivery === 'local') return { delivery, validation, completed: [], failed: [], not_started: [] };
|
|
35
|
+
if (delivery === 'preview') {
|
|
36
|
+
const previews = targets.map((item) => {
|
|
37
|
+
const result = diffResource(projectDir, item.resource_type, item.resource_id);
|
|
38
|
+
if (!flags.stat && !flags.summary) return { changed: result.changed, entry: result.entry, diff: result.output };
|
|
39
|
+
return report(result.entry, [{ path: result.entry.local_path, changed: result.changed, output: result.output,
|
|
40
|
+
base_path: absolutePath(projectDir, result.entry.base_path), local_path: absolutePath(projectDir, result.entry.local_path) }]);
|
|
41
|
+
});
|
|
42
|
+
return { delivery, validation, previews, completed: [], failed: [], not_started: [] };
|
|
18
43
|
}
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
44
|
+
const statuses = [];
|
|
45
|
+
try {
|
|
46
|
+
const completed = await commitBatch(projectDir, targets, { ...options, onStatus: (item) => statuses.push(item) });
|
|
47
|
+
return { delivery, validation, completed, failed: [], not_started: [] };
|
|
48
|
+
} catch (error) {
|
|
49
|
+
const batch = error.details?.batch || error.details;
|
|
50
|
+
return { delivery, validation, error: { code: error.code || 'COMMIT_FAILED', message: error.message },
|
|
51
|
+
...(Array.isArray(batch?.completed) ? batch : {
|
|
52
|
+
completed: statuses.filter((item) => ['committed', 'unchanged'].includes(item.status)),
|
|
53
|
+
failed: statuses.filter((item) => item.status === 'failed'),
|
|
54
|
+
not_started: statuses.length ? statuses.filter((item) => item.status === 'not_started') : targets,
|
|
55
|
+
}) };
|
|
22
56
|
}
|
|
57
|
+
}
|
|
23
58
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
const
|
|
32
|
-
|
|
59
|
+
async function deploy(projectDir, positional, flags = {}) {
|
|
60
|
+
try {
|
|
61
|
+
const delivery = String(flags.delivery || 'deploy').toLowerCase();
|
|
62
|
+
if (!['local', 'preview', 'deploy'].includes(delivery)) throw new Error('--delivery accepts local, preview, or deploy.');
|
|
63
|
+
const targets = positional.length || delivery !== 'local' ? targetsFrom(positional) : null;
|
|
64
|
+
const value = await deliverTargets(projectDir, targets, { ...flags, delivery });
|
|
65
|
+
if (flags.output !== 'json' && value.previews) {
|
|
66
|
+
for (const preview of value.previews) process.stdout.write(flags.stat ? formatStat(preview)
|
|
67
|
+
: flags.summary ? formatSummary(preview) : preview.diff);
|
|
68
|
+
return 0;
|
|
33
69
|
}
|
|
34
|
-
return
|
|
35
|
-
}
|
|
36
|
-
return require('./commit')(projectDir, [resourceType, ...ids], flags);
|
|
70
|
+
return outputResult(value, flags);
|
|
71
|
+
} catch (error) { return outputResult({ error: { code: error.code || 'DEPLOY_FAILED', message: error.message } }, flags); }
|
|
37
72
|
}
|
|
38
73
|
|
|
39
74
|
module.exports = deploy;
|
|
75
|
+
module.exports.targetsFrom = targetsFrom;
|
|
76
|
+
module.exports.deliverTargets = deliverTargets;
|
|
77
|
+
module.exports.outputResult = outputResult;
|
package/src/commands/diff.js
CHANGED
|
@@ -8,12 +8,9 @@ const { absolutePath } = require('../worktree/manifest');
|
|
|
8
8
|
function diff(projectDir, positional, flags = {}) {
|
|
9
9
|
const [resourceType, resourceId] = positional;
|
|
10
10
|
if (!resourceType || !resourceId) {
|
|
11
|
-
log.err('Usage: draftgo diff <pages|nav|docs
|
|
11
|
+
log.err('Usage: draftgo diff <pages|nav|docs> <id>');
|
|
12
12
|
return 1;
|
|
13
13
|
}
|
|
14
|
-
if (require('./customService').isServiceType(resourceType)) {
|
|
15
|
-
return require('./customService').diff(projectDir, [resourceId], flags);
|
|
16
|
-
}
|
|
17
14
|
const result = diffResource(projectDir, resourceType, resourceId);
|
|
18
15
|
const concise = Boolean(flags.stat || flags.summary);
|
|
19
16
|
const value = concise ? report(result.entry, [{
|
package/src/commands/group.js
CHANGED
|
@@ -8,8 +8,7 @@ const OPERATIONS = Object.freeze({
|
|
|
8
8
|
create: 'createUserGroup',
|
|
9
9
|
get: 'getUserGroup',
|
|
10
10
|
update: 'updateUserGroup',
|
|
11
|
-
|
|
12
|
-
remove: 'removeUserGroup',
|
|
11
|
+
remove: 'deleteUserGroup',
|
|
13
12
|
'members.list': 'listUserGroupMembers',
|
|
14
13
|
'members.add': 'addUserGroupMember',
|
|
15
14
|
'members.remove': 'removeUserGroupMember',
|
|
@@ -27,7 +26,7 @@ function operationKey(parts) {
|
|
|
27
26
|
async function groupCommand(projectDir, positional, flags = {}) {
|
|
28
27
|
const key = operationKey(positional);
|
|
29
28
|
if (!OPERATIONS[key]) {
|
|
30
|
-
log.err('Usage: draftgo group list|create|get|update|
|
|
29
|
+
log.err('Usage: draftgo group list|create|get|update|remove | members list|add|remove [--input <json-file>]');
|
|
31
30
|
return 1;
|
|
32
31
|
}
|
|
33
32
|
return callOperation(projectDir, OPERATIONS[key], flags);
|
package/src/commands/help.js
CHANGED
|
@@ -14,19 +14,22 @@ function help() {
|
|
|
14
14
|
console.log(`draftgo v${getPackageVersion()} - DraftGo workbench CLI for AI coding agents
|
|
15
15
|
|
|
16
16
|
DraftGo shell baseline: React + Vite. Database Pages default to native HTML,
|
|
17
|
-
Tailwind CSS 4, and
|
|
18
|
-
|
|
19
|
-
|
|
17
|
+
Tailwind CSS 4, and the DraftGo built-in component library (draftgo/*).
|
|
18
|
+
Provider brands and shared icons are served from the local /assets/providers and
|
|
19
|
+
/assets/icons directories; the Page runtime does not require third-party CDNs.
|
|
20
|
+
System MCP handles live discovery and structured resources; complete page,
|
|
21
|
+
navigation, and document bodies use checkout/commit outside MCP context.
|
|
20
22
|
The installed Skill routes agents to task-specific References and MCP tools.
|
|
21
23
|
|
|
22
24
|
Usage:
|
|
23
25
|
draftgo init [<target>...] Install the DraftGo Skill. No target = detect.
|
|
24
26
|
Use "all" to install every Skill target.
|
|
25
|
-
draftgo update [<target>...] Fully update the global CLI, then atomically
|
|
26
|
-
refresh installed
|
|
27
|
+
draftgo update [<target>...] Fully update the global CLI, then atomically
|
|
28
|
+
refresh installed Skills. An explicit target
|
|
29
|
+
may also install that target when missing.
|
|
27
30
|
draftgo uninstall <target|all> Remove Skill files. --purge also removes
|
|
28
31
|
the entire .draftgo/ runtime directory.
|
|
29
|
-
draftgo status Show connection health,
|
|
32
|
+
draftgo status Show connection health, Registry revision, targets, and Skill version.
|
|
30
33
|
|
|
31
34
|
draftgo connect [<target>...] Verify and save server/API Key, then configure
|
|
32
35
|
a detected or explicit MCP host. This never
|
|
@@ -40,10 +43,8 @@ Usage:
|
|
|
40
43
|
overlay matching local checkout state.
|
|
41
44
|
Use --route/--title for exact selection.
|
|
42
45
|
draftgo checkout <type> <id...> Download a long-form body + verified base,
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
draftgo check [custom-services <id...>]
|
|
46
|
-
Validate all checkouts or selected custom services.
|
|
46
|
+
--force explicitly replaces local changes.
|
|
47
|
+
draftgo check Validate all checked-out content.
|
|
47
48
|
--remote also compares remote hash/version.
|
|
48
49
|
draftgo verify [<type> <id...>] Run the default delivery verification.
|
|
49
50
|
Browser options are explicit and optional.
|
|
@@ -65,13 +66,6 @@ Usage:
|
|
|
65
66
|
draftgo components export <library> [--file <zip>]
|
|
66
67
|
Transfer standard DraftGo component archives.
|
|
67
68
|
draftgo refresh <type> <id...> Safely refresh a clean checkout from the cloud.
|
|
68
|
-
draftgo validate custom-services <id>
|
|
69
|
-
Build and inspect the current cloud draft.
|
|
70
|
-
draftgo test custom-services <id> [--source <source>] [--input <file>] [--handler <selector>]
|
|
71
|
-
Run the cloud draft in the DraftGo Runner.
|
|
72
|
-
draftgo publish custom-services <id...>
|
|
73
|
-
Publish current validated drafts; batch errors
|
|
74
|
-
report services already completed.
|
|
75
69
|
draftgo reconcile <type> <id...> Repair stale metadata only when local equals remote.
|
|
76
70
|
draftgo conflicts List unresolved conflicts; --all includes resolved.
|
|
77
71
|
draftgo conflict show <type> <id>
|
|
@@ -81,28 +75,25 @@ Usage:
|
|
|
81
75
|
preserved remote base; then check/diff/commit.
|
|
82
76
|
draftgo clean [--dry-run|--yes] Plan or remove all tmp and registered artifacts.
|
|
83
77
|
draftgo work start <item> Add an active item to .draftgo/worklog.md.
|
|
84
|
-
draftgo work add <item> Add a
|
|
78
|
+
draftgo work add <item> Add an item awaiting a decision.
|
|
79
|
+
draftgo work wait <ref> Mark an item waiting; --note records the reason.
|
|
85
80
|
draftgo work start-item <ref> Mark an item active; ref is number or date#number.
|
|
86
81
|
draftgo work complete <ref> Mark an item complete; --note appends evidence.
|
|
87
82
|
draftgo work show|list Show the worklog or its structured item list.
|
|
88
83
|
|
|
89
|
-
draftgo api <query> Search the live API contract through MCP.
|
|
84
|
+
draftgo api <query> Search the live API contract through MCP.
|
|
85
|
+
draftgo api search <query> Search the live operation registry explicitly.
|
|
90
86
|
draftgo api describe <operation_id>
|
|
91
87
|
Describe one live API operation through MCP.
|
|
92
88
|
draftgo api call <operation_id> --input <json-file>
|
|
93
89
|
Call one described operation with UTF-8 JSON.
|
|
94
90
|
draftgo capabilities list|search|show|audit
|
|
95
91
|
Discover and audit the current server's live operation catalog.
|
|
96
|
-
draftgo
|
|
97
|
-
draftgo
|
|
98
|
-
draftgo grant list|create|get|revoke
|
|
99
|
-
Manage platform/space AccessGrants.
|
|
100
|
-
draftgo api-key status|create|update|delete|rotate|reset|enable|disable
|
|
92
|
+
draftgo group <action> Manage RBAC groups and group members.
|
|
93
|
+
draftgo api-key status|create|update|delete|rotate
|
|
101
94
|
Manage the current user's API key through MCP.
|
|
102
95
|
draftgo role permissions|list|create|get|update|delete
|
|
103
96
|
Manage structured permission templates.
|
|
104
|
-
draftgo data-range list|create|get|update|batch|delete
|
|
105
|
-
Manage db_meta record policies (none|owner|all).
|
|
106
97
|
draftgo delete <operation_id> [id]
|
|
107
98
|
Confirm and call a live delete operation.
|
|
108
99
|
draftgo deploy [<type> <id...>] Check, then diff or commit checked-out content.
|
|
@@ -117,8 +108,8 @@ Usage:
|
|
|
117
108
|
draftgo -v | --version Print CLI version.
|
|
118
109
|
draftgo -h | --help Show this help.
|
|
119
110
|
|
|
120
|
-
Resource types:
|
|
121
|
-
pages | nav/navigations | docs/articles
|
|
111
|
+
Resource types:
|
|
112
|
+
pages | nav/navigations | docs/articles
|
|
122
113
|
|
|
123
114
|
Important flags:
|
|
124
115
|
--project <dir> Operate on <dir> instead of the current directory.
|
|
@@ -127,8 +118,6 @@ Important flags:
|
|
|
127
118
|
--mcp-url <url> (connect) Explicit endpoint; standard /mcp derives the
|
|
128
119
|
base URL; custom paths also need --server.
|
|
129
120
|
--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.
|
|
132
121
|
--timeout <ms> (connect/mcp test) Network timeout.
|
|
133
122
|
--allow-offline (connect) Save only after explicitly accepting a
|
|
134
123
|
failed MCP validation.
|
|
@@ -139,8 +128,8 @@ Important flags:
|
|
|
139
128
|
--connect (init) Continue into DraftGo server connection.
|
|
140
129
|
--no-setup (init) Install the Skill without either setup flow.
|
|
141
130
|
--output json Print machine-readable output where supported.
|
|
142
|
-
--type <type> (map) pages | nav/navigations | docs/articles
|
|
143
|
-
|
|
131
|
+
--type <type> (map) pages | nav/navigations | docs/articles;
|
|
132
|
+
(capabilities) alias for a Registry module filter.
|
|
144
133
|
--route <path> (map) Select resources with this exact route.
|
|
145
134
|
--title <title> (map) Select resources with this exact title.
|
|
146
135
|
--limit <1-100> (map) Maximum resources returned per type/page;
|
|
@@ -153,15 +142,7 @@ Important flags:
|
|
|
153
142
|
--yes Skip supported confirmation prompts.
|
|
154
143
|
--operation-id <id> (delete) Select an operation explicitly.
|
|
155
144
|
--params <json> (api call/delete) Pass an API parameter object.
|
|
156
|
-
--input <file> (api call/delete
|
|
157
|
-
JSON object.
|
|
158
|
-
--handler <selector> (custom-service test) route:METHOD:/path, event:name,
|
|
159
|
-
scheduled:name, or a handler name.
|
|
160
|
-
--source <source> (custom-service test) draft (default), auto, or published.
|
|
161
|
-
--headers/--user <file> (custom-service test) Read JSON test identity data.
|
|
162
|
-
--test-write (custom-service test) Permit declared write testing.
|
|
163
|
-
--side-effect-policy <mode>
|
|
164
|
-
(custom-service test) deny | mock | live; default deny.
|
|
145
|
+
--input <file> (api call/delete) Read a UTF-8 JSON object.
|
|
165
146
|
--delivery <mode> (deploy) local | preview | deploy.
|
|
166
147
|
--dry-run Preview supported cleanup or delivery operations.
|
|
167
148
|
--ui <mode> (verify) always | never; default never.
|
|
@@ -196,8 +177,6 @@ Examples:
|
|
|
196
177
|
draftgo verify pages 42
|
|
197
178
|
draftgo diff pages 42 --stat
|
|
198
179
|
draftgo commit pages 42
|
|
199
|
-
draftgo checkout custom-services 12
|
|
200
|
-
draftgo test custom-services 12 --handler route:POST:/health --input request.json
|
|
201
180
|
draftgo work start "Build document management and role permissions"
|
|
202
181
|
draftgo work complete 1 --note "Verification and delivery passed"
|
|
203
182
|
draftgo deploy docs 7 --delivery preview
|
package/src/commands/init.js
CHANGED
|
@@ -15,20 +15,28 @@ function showEnvironment() {
|
|
|
15
15
|
|
|
16
16
|
async function init(projectDir, positional, flags) {
|
|
17
17
|
log.title('draftgo init');
|
|
18
|
+
const interactive = Boolean(process.stdin.isTTY && process.stdout.isTTY) && !(flags.yes || flags.y);
|
|
18
19
|
|
|
19
20
|
// 1) Figure out which targets to install.
|
|
20
21
|
let resolved = [];
|
|
21
22
|
let unknown = [];
|
|
22
23
|
|
|
23
24
|
if (positional.length === 0) {
|
|
24
|
-
|
|
25
|
+
let hits = detectTargets(projectDir);
|
|
25
26
|
if (hits.length === 0) {
|
|
26
27
|
log.warn('未在当前项目检测到任何支持的 AI 工具目录。');
|
|
27
|
-
log.dim(' 使用 `draftgo init all` 或 `draftgo init <target>` 手动指定。');
|
|
28
28
|
log.dim(` 支持列表:${all.map((i) => i.name).join(', ')}`);
|
|
29
|
-
|
|
29
|
+
if (!interactive) {
|
|
30
|
+
log.dim(' 使用 `draftgo init <target>` 手动指定,例如 `draftgo init codex`。');
|
|
31
|
+
return 1;
|
|
32
|
+
}
|
|
33
|
+
hits = String(await ask('请选择你的 AI 工具,例如 codex')).trim().split(/[\s,]+/);
|
|
30
34
|
}
|
|
31
35
|
({ resolved, unknown } = resolveTargets(hits));
|
|
36
|
+
if (unknown.length || !resolved.length) {
|
|
37
|
+
log.err(`未知 target:${hits.join(', ')}`);
|
|
38
|
+
return 1;
|
|
39
|
+
}
|
|
32
40
|
log.info(`自动识别到:${resolved.map((r) => r.displayName).join(', ')}`);
|
|
33
41
|
} else {
|
|
34
42
|
({ resolved, unknown } = resolveTargets(positional));
|
|
@@ -77,7 +85,6 @@ async function init(projectDir, positional, flags) {
|
|
|
77
85
|
const hasConfig = exists(cfgPath);
|
|
78
86
|
const flagConnect = flags.connect === true;
|
|
79
87
|
const flagSkip = flags['no-setup'] === true;
|
|
80
|
-
const interactive = process.stdin.isTTY && process.stdout.isTTY;
|
|
81
88
|
|
|
82
89
|
if (!hasConfig && !flagSkip) {
|
|
83
90
|
// Non-interactive setup can connect immediately with a server and API Key.
|
|
@@ -92,7 +99,7 @@ async function init(projectDir, positional, flags) {
|
|
|
92
99
|
log.plain(` ${log.c.cyan('[A]')} 连接基座服务`);
|
|
93
100
|
log.dim(' 使用已有 DraftGo 服务,接下来输入 BaseURL 和系统访问令牌。');
|
|
94
101
|
log.plain(` ${log.c.cyan('[B]')} 本地启动基座`);
|
|
95
|
-
log.dim(' 使用 Docker 启动 DraftGo
|
|
102
|
+
log.dim(' 使用 Docker 启动 DraftGo 和独立 Redis;按需准备 MySQL 和 Qdrant。');
|
|
96
103
|
log.plain(` ${log.c.cyan('[C]')} 稍后自行处理`);
|
|
97
104
|
log.dim(' 仅安装 Skill,不写入服务配置,也不创建容器。');
|
|
98
105
|
const choice = (await ask('请选择 [A/B/C]', { default: 'C' })).trim().toUpperCase();
|
|
@@ -100,7 +107,7 @@ async function init(projectDir, positional, flags) {
|
|
|
100
107
|
return await require('./connect')(projectDir, [], flags);
|
|
101
108
|
}
|
|
102
109
|
if (choice === 'B') {
|
|
103
|
-
return await require('../localRuntime').runWizard(projectDir, { yes: true });
|
|
110
|
+
return await require('../localRuntime').runWizard(projectDir, { yes: true, interactive: true });
|
|
104
111
|
}
|
|
105
112
|
if (choice !== 'C') {
|
|
106
113
|
log.warn('无效选择,已跳过基座处理。');
|
package/src/commands/local.js
CHANGED
|
@@ -57,7 +57,10 @@ function local(projectDir, positional, flags = {}) {
|
|
|
57
57
|
|
|
58
58
|
switch (action) {
|
|
59
59
|
case 'setup':
|
|
60
|
-
return runWizard(projectDir, {
|
|
60
|
+
return runWizard(projectDir, {
|
|
61
|
+
yes: !!(flags.yes || flags.y),
|
|
62
|
+
...(flags.params ? { params: flags.params } : {}),
|
|
63
|
+
});
|
|
61
64
|
case 'start':
|
|
62
65
|
return runCompose(projectDir, ['up', '-d']);
|
|
63
66
|
case 'stop':
|