Procházet zdrojové kódy

fix(docs): parse inserted composition rows

Turtle před 2 měsíci
rodič
revize
a01c1bccd6
2 změnil soubory, kde provedl 63 přidání a 21 odebrání
  1. 45 3
      apps/cli/composition.md
  2. 18 18
      scripts/gen-doc-graphs.ts

+ 45 - 3
apps/cli/composition.md

@@ -96,8 +96,36 @@ flowchart LR
   cfg --> plugin_tui_fs_local
   plugin_tui_llm_deepseek["llm-deepseek<br/>@deepseek-ai/dsh-llm-deepseek"]
   cfg --> plugin_tui_llm_deepseek
-  plugin_tui_tools["tools<br/>@deepseek-ai/dsh-tool-ask-user"]
-  cfg --> plugin_tui_tools
+  plugin_tui_hmr["hmr<br/>@cordisjs/plugin-hmr"]
+  cfg --> plugin_tui_hmr
+  plugin_tui_invariants["invariants<br/>@deepseek-ai/dsh-invariants"]
+  cfg --> plugin_tui_invariants
+  plugin_tui_session_invariant["session-invariant<br/>@deepseek-ai/dsh-session/invariant"]
+  cfg --> plugin_tui_session_invariant
+  plugin_tui_agent_invariant["agent-invariant<br/>@deepseek-ai/dsh-agent/invariant"]
+  cfg --> plugin_tui_agent_invariant
+  plugin_tui_scope_invariant["scope-invariant<br/>@deepseek-ai/dsh-scope/invariant"]
+  cfg --> plugin_tui_scope_invariant
+  plugin_tui_agent_loop_invariant["agent-loop-invariant<br/>@deepseek-ai/dsh-agent-loop/invariant"]
+  cfg --> plugin_tui_agent_loop_invariant
+  plugin_tui_session_checkpoint_policy["session-checkpoint-policy<br/>@deepseek-ai/dsh-session-checkpoint-policy"]
+  cfg --> plugin_tui_session_checkpoint_policy
+  plugin_tui_session_query_sqlite["session-query-sqlite<br/>@deepseek-ai/dsh-session-query-sqlite"]
+  cfg --> plugin_tui_session_query_sqlite
+  plugin_tui_session_reference["session-reference<br/>@deepseek-ai/dsh-session-reference"]
+  cfg --> plugin_tui_session_reference
+  plugin_tui_tool_result_prune["tool-result-prune<br/>@deepseek-ai/dsh-compact-tool-result-prune"]
+  cfg --> plugin_tui_tool_result_prune
+  plugin_tui_tool_goal["tool-goal<br/>@deepseek-ai/dsh-tool-goal"]
+  cfg --> plugin_tui_tool_goal
+  plugin_tui_tool_ralph["tool-ralph<br/>@deepseek-ai/dsh-tool-ralph"]
+  cfg --> plugin_tui_tool_ralph
+  plugin_tui_tui_prompt["tui-prompt<br/>@deepseek-ai/dsh-tui/prompt"]
+  cfg --> plugin_tui_tui_prompt
+  plugin_tui_tui["tui<br/>@deepseek-ai/dsh-tui"]
+  cfg --> plugin_tui_tui
+  plugin_tui_tool_ask_user["tool-ask-user<br/>@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).
 

+ 18 - 18
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,31 +567,30 @@ function renderCapabilitySeams(pkgs: Pkg[]): string {
   return lines.join('\n')
 }
 
+const jsExpressionType = new Type('tag:yaml.org,2002:js', {
+  kind: 'scalar',
+  construct: (value: string | null): string => value ?? '',
+})
+const cordisSchema = DEFAULT_SCHEMA.extend([jsExpressionType])
+
 function parseExampleCordis(rel: string): ExamplePlugin[] {
-  const text = readFileSync(resolve(root, rel), 'utf8')
+  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[] = []
-  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 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)
     }
-    const name = /^\s+name:\s+(.+?)\s*$/.exec(line)
-    if (name?.[1] !== undefined && current) current.name = stripYamlScalar(name[1])
   }
-  flush()
+  visit(document)
   return plugins
 }
 
-function stripYamlScalar(value: string): string {
-  return value.trim().replace(/^['"]|['"]$/g, '')
-}
-
 const APP_EXAMPLES = [
   {
     id: 'tui',