Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions apps/cli/scripts/export-sdk-contract.ts
Original file line number Diff line number Diff line change
Expand Up @@ -307,6 +307,8 @@ function buildSdkContract() {
entry.outputSchema = docOp.outputSchema;
if (docOp.successSchema) entry.successSchema = docOp.successSchema;
if (docOp.failureSchema) entry.failureSchema = docOp.failureSchema;
if (docOp.skipAsATool) entry.skipAsATool = true;
if (docOp.essential) entry.essential = true;
} else {
// CLI-only operation — metadata from canonical definitions
const def = cliOnlyDef!;
Expand All @@ -315,6 +317,7 @@ function buildSdkContract() {
entry.supportsTrackedMode = def.sdkMetadata.supportsTrackedMode;
entry.supportsDryRun = def.sdkMetadata.supportsDryRun;
entry.outputSchema = def.outputSchema;
if (def.skipAsATool) entry.skipAsATool = true;
}

// Invariant: every operation must have outputSchema
Expand Down
4 changes: 2 additions & 2 deletions apps/cli/src/__tests__/conformance/scenarios.ts
Original file line number Diff line number Diff line change
Expand Up @@ -858,7 +858,7 @@ export const SUCCESS_SCENARIOS = {
docPath,
'--expected-revision',
'0',
'--atomic-json',
'--atomic',
'true',
'--change-mode',
'direct',
Expand Down Expand Up @@ -891,7 +891,7 @@ export const SUCCESS_SCENARIOS = {
'mutations',
'apply',
docPath,
'--atomic-json',
'--atomic',
'true',
'--change-mode',
'direct',
Expand Down
2 changes: 1 addition & 1 deletion apps/cli/src/__tests__/help-regression.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ describe('CLI help regression coverage', () => {
);

expect(blocksDeleteCommand).toBeDefined();
expect(CLI_HELP).toContain('blocks:');
expect(CLI_HELP).toContain('core:');
expect(CLI_HELP).toContain(blocksDeleteCommand!.key);
});
});
16 changes: 10 additions & 6 deletions apps/cli/src/cli/cli-only-operation-definitions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ export interface CliOnlyOperationDefinition {
intentName: string;
sdkMetadata: CliOnlySdkMetadata;
outputSchema: Record<string, unknown>;
/** When true, this operation is excluded from generated LLM tool catalogs. */
skipAsATool?: boolean;
}

// ---------------------------------------------------------------------------
Expand All @@ -39,7 +41,7 @@ export interface CliOnlyOperationDefinition {

export const CLI_ONLY_OPERATION_DEFINITIONS: Record<CliOnlyOperation, CliOnlyOperationDefinition> = {
open: {
category: 'lifecycle',
category: 'session',
description:
'Open a document and create a persistent editing session. Optionally override the document body with contentOverride + overrideType (markdown, html, or text).',
requiresDocumentContext: false,
Expand Down Expand Up @@ -78,7 +80,7 @@ export const CLI_ONLY_OPERATION_DEFINITIONS: Record<CliOnlyOperation, CliOnlyOpe
},
},
save: {
category: 'lifecycle',
category: 'session',
description: 'Save the current session to the original file or a new path.',
requiresDocumentContext: false,
intentName: 'save_document',
Expand Down Expand Up @@ -117,7 +119,7 @@ export const CLI_ONLY_OPERATION_DEFINITIONS: Record<CliOnlyOperation, CliOnlyOpe
},
},
close: {
category: 'lifecycle',
category: 'session',
description: 'Close the active editing session and clean up resources.',
requiresDocumentContext: false,
intentName: 'close_document',
Expand All @@ -144,7 +146,7 @@ export const CLI_ONLY_OPERATION_DEFINITIONS: Record<CliOnlyOperation, CliOnlyOpe
},
},
status: {
category: 'introspection',
category: 'session',
description: 'Show the current session status and document metadata.',
requiresDocumentContext: false,
intentName: 'get_status',
Expand All @@ -168,10 +170,11 @@ export const CLI_ONLY_OPERATION_DEFINITIONS: Record<CliOnlyOperation, CliOnlyOpe
},
},
describe: {
category: 'introspection',
category: 'session',
description: 'List all available CLI operations and contract metadata.',
requiresDocumentContext: false,
intentName: 'describe_commands',
skipAsATool: true,
sdkMetadata: { mutates: false, idempotency: 'idempotent', supportsTrackedMode: false, supportsDryRun: false },
outputSchema: {
type: 'object',
Expand All @@ -194,11 +197,12 @@ export const CLI_ONLY_OPERATION_DEFINITIONS: Record<CliOnlyOperation, CliOnlyOpe
},
},
describeCommand: {
category: 'introspection',
category: 'session',
description: 'Show detailed metadata for a single CLI operation.',
requiresDocumentContext: false,
tokenOverride: ['describe', 'command'],
intentName: 'describe_command',
skipAsATool: true,
sdkMetadata: { mutates: false, idempotency: 'idempotent', supportsTrackedMode: false, supportsDryRun: false },
outputSchema: {
type: 'object',
Expand Down
11 changes: 6 additions & 5 deletions apps/cli/src/cli/commands.ts
Original file line number Diff line number Diff line change
Expand Up @@ -158,17 +158,18 @@ function buildHelpText(): string {
}

const categoryOrder = [
'query',
'mutation',
'core',
'format',
'create',
'blocks',
'tables',
'sections',
'lists',
'comments',
'trackChanges',
'lifecycle',
'toc',
'images',
'history',
'session',
'introspection',
];

for (const category of categoryOrder) {
Expand Down
19 changes: 5 additions & 14 deletions apps/cli/src/cli/operation-params.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,7 @@ const CHANGE_MODE_PARAM: CliOperationParamSpec = {
kind: 'flag',
flag: 'change-mode',
type: 'string',
schema: { oneOf: [{ const: 'direct' }, { const: 'tracked' }] } as CliTypeSpec,
agentVisible: false,
schema: { enum: ['direct', 'tracked'] } as CliTypeSpec,
};
const EXPECTED_REVISION_PARAM: CliOperationParamSpec = {
name: 'expectedRevision',
Expand All @@ -79,7 +78,7 @@ const USER_EMAIL_PARAM: CliOperationParamSpec = {
// ---------------------------------------------------------------------------

type JsonSchema = Record<string, unknown>;
const AGENT_HIDDEN_PARAM_NAMES = new Set(['out', 'expectedRevision', 'changeMode', 'dryRun']);
const AGENT_HIDDEN_PARAM_NAMES = new Set(['out', 'expectedRevision', 'dryRun']);

function resolveRef(schema: JsonSchema, $defs?: Record<string, JsonSchema>): JsonSchema {
if (schema.$ref && $defs) {
Expand Down Expand Up @@ -288,19 +287,11 @@ const PARAM_FLAG_OVERRIDES: Partial<Record<string, Record<string, { name?: strin
// ---------------------------------------------------------------------------
// Per-operation param schema overrides
//
// Some contract schemas intentionally use broad placeholders (for example,
// mutation-step arrays represented as { type: 'object' }). Validate these
// payloads as generic JSON to avoid over-constraining CLI flags.
// Override specific parameter schemas when the contract schema needs
// adjustment for CLI metadata (e.g. simplifying or enriching).
// ---------------------------------------------------------------------------

const PARAM_SCHEMA_OVERRIDES: Partial<Record<string, Record<string, CliTypeSpec>>> = {
'doc.mutations.preview': {
steps: { type: 'json' },
},
'doc.mutations.apply': {
steps: { type: 'json' },
},
};
const PARAM_SCHEMA_OVERRIDES: Partial<Record<string, Record<string, CliTypeSpec>>> = {};

// ---------------------------------------------------------------------------
// Schema-derived param exclusions
Expand Down
30 changes: 23 additions & 7 deletions apps/cli/src/cli/operation-set.ts
Original file line number Diff line number Diff line change
Expand Up @@ -86,15 +86,31 @@ for (const group of REFERENCE_OPERATION_GROUPS) {
}
}

const REFERENCE_GROUP_TO_CATEGORY: Record<string, CliCategory> = {
core: 'core',
mutations: 'core',
query: 'core',
blocks: 'core',
capabilities: 'core',
format: 'format',
'format.paragraph': 'format',
styles: 'format',
'styles.paragraph': 'format',
create: 'create',
tables: 'tables',
sections: 'sections',
lists: 'lists',
comments: 'comments',
trackChanges: 'trackChanges',
toc: 'toc',
images: 'images',
history: 'history',
};

function deriveCategoryFromDocApi(docApiId: OperationId): CliCategory {
const group = REFERENCE_GROUP_BY_OP.get(docApiId);
if (!group) return 'query';

if (group === 'core' || group === 'mutations') {
return COMMAND_CATALOG[docApiId].mutates ? 'mutation' : 'query';
}

return group as CliCategory;
if (!group) return 'core';
return REFERENCE_GROUP_TO_CATEGORY[group] ?? 'core';
}

export function cliCategory(cliOpId: CliOperationId): CliCategory {
Expand Down
13 changes: 6 additions & 7 deletions apps/cli/src/cli/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -115,19 +115,18 @@ export type CliOperationArgsById = {
// ---------------------------------------------------------------------------

export type CliCategory =
| 'query'
| 'mutation'
| 'core'
| 'format'
| 'create'
| 'blocks'
| 'tables'
| 'sections'
| 'lists'
| 'comments'
| 'trackChanges'
| 'capabilities'
| 'toc'
| 'images'
| 'history'
| 'lifecycle'
| 'session'
| 'introspection';
| 'session';

/** The 10 CLI-only operation identifiers (without `doc.` prefix). Single source of truth. */
export const CLI_ONLY_OPERATIONS = [
Expand Down
7 changes: 7 additions & 0 deletions apps/cli/src/lib/operation-args.ts
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,13 @@ export function validateValueAgainstTypeSpec(value: unknown, schema: CliTypeSpec

if (schema.type === 'json') return;

if (schema.enum) {
if (!schema.enum.includes(value)) {
throw new CliError('VALIDATION_ERROR', `${path} must be one of: ${schema.enum.join(', ')}.`);
}
return;
}

if (schema.type === 'string') {
if (typeof value !== 'string') throw new CliError('VALIDATION_ERROR', `${path} must be a string.`);
return;
Expand Down
13 changes: 12 additions & 1 deletion apps/docs/docs.json
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,14 @@
},
"document-engine/sdks",
"document-engine/cli",
"document-engine/mcp"
{
"group": "AI Agents",
"pages": [
"document-engine/ai-agents/llm-tools",
"document-engine/ai-agents/skills",
"document-engine/ai-agents/mcp-server"
]
}
]
},
{
Expand Down Expand Up @@ -307,6 +314,10 @@
]
},
"redirects": [
{
"source": "/document-engine/mcp",
"destination": "/document-engine/ai-agents/mcp-server"
},
{
"source": "/core/superdoc/properties",
"destination": "/core/superdoc/methods#properties"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -555,5 +555,5 @@
}
],
"marker": "{/* GENERATED FILE: DO NOT EDIT. Regenerate via `pnpm run docapi:sync`. */}",
"sourceHash": "de6b000cae7d5e94443948d7401a56c0c835d2718f70f2298502956d379a57b1"
"sourceHash": "185b9ab20679d6709e676a2b2b810adebddb201298e6a1682b3af62e600e4eb1"
}
Loading
Loading