From a01c1bccd691db032ced3a00b94e469567de7998 Mon Sep 17 00:00:00 2001 From: Turtle Date: Wed, 29 Jul 2026 21:30:51 +0800 Subject: [PATCH] fix(docs): parse inserted composition rows --- apps/cli/composition.md | 48 ++++++++++++++++++++++++++++++++++++--- scripts/gen-doc-graphs.ts | 44 +++++++++++++++++------------------ 2 files changed, 67 insertions(+), 25 deletions(-) diff --git a/apps/cli/composition.md b/apps/cli/composition.md index 9c0d5b5f06..0e2af8b863 100644 --- a/apps/cli/composition.md +++ b/apps/cli/composition.md @@ -96,8 +96,36 @@ flowchart LR cfg --> plugin_tui_fs_local plugin_tui_llm_deepseek["llm-deepseek
@deepseek-ai/dsh-llm-deepseek"] cfg --> plugin_tui_llm_deepseek - plugin_tui_tools["tools
@deepseek-ai/dsh-tool-ask-user"] - cfg --> plugin_tui_tools + plugin_tui_hmr["hmr
@cordisjs/plugin-hmr"] + cfg --> plugin_tui_hmr + plugin_tui_invariants["invariants
@deepseek-ai/dsh-invariants"] + cfg --> plugin_tui_invariants + plugin_tui_session_invariant["session-invariant
@deepseek-ai/dsh-session/invariant"] + cfg --> plugin_tui_session_invariant + plugin_tui_agent_invariant["agent-invariant
@deepseek-ai/dsh-agent/invariant"] + cfg --> plugin_tui_agent_invariant + plugin_tui_scope_invariant["scope-invariant
@deepseek-ai/dsh-scope/invariant"] + cfg --> plugin_tui_scope_invariant + plugin_tui_agent_loop_invariant["agent-loop-invariant
@deepseek-ai/dsh-agent-loop/invariant"] + cfg --> plugin_tui_agent_loop_invariant + plugin_tui_session_checkpoint_policy["session-checkpoint-policy
@deepseek-ai/dsh-session-checkpoint-policy"] + cfg --> plugin_tui_session_checkpoint_policy + plugin_tui_session_query_sqlite["session-query-sqlite
@deepseek-ai/dsh-session-query-sqlite"] + cfg --> plugin_tui_session_query_sqlite + plugin_tui_session_reference["session-reference
@deepseek-ai/dsh-session-reference"] + cfg --> plugin_tui_session_reference + plugin_tui_tool_result_prune["tool-result-prune
@deepseek-ai/dsh-compact-tool-result-prune"] + cfg --> plugin_tui_tool_result_prune + plugin_tui_tool_goal["tool-goal
@deepseek-ai/dsh-tool-goal"] + cfg --> plugin_tui_tool_goal + plugin_tui_tool_ralph["tool-ralph
@deepseek-ai/dsh-tool-ralph"] + cfg --> plugin_tui_tool_ralph + plugin_tui_tui_prompt["tui-prompt
@deepseek-ai/dsh-tui/prompt"] + cfg --> plugin_tui_tui_prompt + plugin_tui_tui["tui
@deepseek-ai/dsh-tui"] + cfg --> plugin_tui_tui + plugin_tui_tool_ask_user["tool-ask-user
@deepseek-ai/dsh-tool-ask-user"] + cfg --> plugin_tui_tool_ask_user ``` | Plugin id | Package / module | @@ -146,7 +174,21 @@ flowchart LR | `agent-loop` | `@deepseek-ai/dsh-agent-loop` | | `fs-local` | `@deepseek-ai/dsh-fs-local` | | `llm-deepseek` | `@deepseek-ai/dsh-llm-deepseek` | -| `tools` | `@deepseek-ai/dsh-tool-ask-user` | +| `hmr` | `@cordisjs/plugin-hmr` | +| `invariants` | `@deepseek-ai/dsh-invariants` | +| `session-invariant` | `@deepseek-ai/dsh-session/invariant` | +| `agent-invariant` | `@deepseek-ai/dsh-agent/invariant` | +| `scope-invariant` | `@deepseek-ai/dsh-scope/invariant` | +| `agent-loop-invariant` | `@deepseek-ai/dsh-agent-loop/invariant` | +| `session-checkpoint-policy` | `@deepseek-ai/dsh-session-checkpoint-policy` | +| `session-query-sqlite` | `@deepseek-ai/dsh-session-query-sqlite` | +| `session-reference` | `@deepseek-ai/dsh-session-reference` | +| `tool-result-prune` | `@deepseek-ai/dsh-compact-tool-result-prune` | +| `tool-goal` | `@deepseek-ai/dsh-tool-goal` | +| `tool-ralph` | `@deepseek-ai/dsh-tool-ralph` | +| `tui-prompt` | `@deepseek-ai/dsh-tui/prompt` | +| `tui` | `@deepseek-ai/dsh-tui` | +| `tool-ask-user` | `@deepseek-ai/dsh-tool-ask-user` | Source configs: [`apps/cli/base.cordis.yml`](base.cordis.yml), [`apps/cli/tui.cordis.yml`](tui.cordis.yml). diff --git a/scripts/gen-doc-graphs.ts b/scripts/gen-doc-graphs.ts index 54cdc11a50..642f97db66 100644 --- a/scripts/gen-doc-graphs.ts +++ b/scripts/gen-doc-graphs.ts @@ -8,6 +8,7 @@ import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs' import { dirname, relative, resolve } from 'node:path' import ts from 'typescript' +import { DEFAULT_SCHEMA, load, Type } from 'js-yaml' import { collectEvents, collectServices } from './gen-cordis-catalog.ts' import { collectPackageGraph, @@ -566,29 +567,28 @@ function renderCapabilitySeams(pkgs: Pkg[]): string { return lines.join('\n') } -function parseExampleCordis(rel: string): ExamplePlugin[] { - const text = readFileSync(resolve(root, rel), 'utf8') - const plugins: ExamplePlugin[] = [] - let current: { id: string; name?: string } | null = null - const flush = (): void => { - if (current?.name) plugins.push({ id: current.id, name: current.name }) - } - for (const line of text.split('\n')) { - const id = /^-\s+id:\s+(.+?)\s*$/.exec(line) - if (id?.[1] !== undefined) { - flush() - current = { id: stripYamlScalar(id[1]) } - continue - } - const name = /^\s+name:\s+(.+?)\s*$/.exec(line) - if (name?.[1] !== undefined && current) current.name = stripYamlScalar(name[1]) - } - flush() - return plugins -} +const jsExpressionType = new Type('tag:yaml.org,2002:js', { + kind: 'scalar', + construct: (value: string | null): string => value ?? '', +}) +const cordisSchema = DEFAULT_SCHEMA.extend([jsExpressionType]) -function stripYamlScalar(value: string): string { - return value.trim().replace(/^['"]|['"]$/g, '') +function parseExampleCordis(rel: string): ExamplePlugin[] { + const document = load(readFileSync(resolve(root, rel), 'utf8'), { schema: cordisSchema }) + if (!Array.isArray(document)) throw new Error(`${rel}: expected a top-level config array`) + const plugins: ExamplePlugin[] = [] + const visit = (entries: unknown[]): void => { + for (const value of entries) { + if (typeof value !== 'object' || value === null || Array.isArray(value)) continue + const entry = value as { id?: unknown; name?: unknown; insert?: unknown } + if (typeof entry.id === 'string' && typeof entry.name === 'string') { + plugins.push({ id: entry.id, name: entry.name }) + } + if (Array.isArray(entry.insert)) visit(entry.insert) + } + } + visit(document) + return plugins } const APP_EXAMPLES = [