|
16 | 16 | * no-noise behavior on installs with no coding agent. |
17 | 17 | * - ON: core registers the AGENTS.md composable file (so `wp datamachine memory |
18 | 18 | * compose AGENTS.md` writes it and auto-regeneration keeps it fresh) and the |
19 | | - * core-owned sections, including the `datamachine` section whose command list |
20 | | - * is REFLECTED from core's registered command classes (never hand-typed). |
| 19 | + * core-owned sections, including concise Data Machine routing and discovery |
| 20 | + * guidance. The live CLI help remains the complete command authority. |
21 | 21 | * |
22 | 22 | * Why composition lives in core: core already owns SectionRegistry, |
23 | 23 | * MemoryFileRegistry, ComposableFileGenerator, ComposableFileInvalidation, and |
|
32 | 32 |
|
33 | 33 | use DataMachine\Engine\AI\MemoryFileRegistry; |
34 | 34 | use DataMachine\Engine\AI\SectionRegistry; |
35 | | -use DataMachine\Cli\CommandRegistry; |
36 | 35 |
|
37 | 36 | /** |
38 | 37 | * Whether AGENTS.md composition is enabled for this install. |
@@ -86,7 +85,7 @@ function datamachine_register_agents_md_file(): void { |
86 | 85 | * |
87 | 86 | * Sections registered here describe Data Machine itself. The external coding |
88 | 87 | * runtime installer owns generic WordPress coding guidance, while Data Machine |
89 | | - * Code owns its `datamachine-code` section and workspace inventory. |
| 88 | + * Code owns its workspace lifecycle section. |
90 | 89 | * |
91 | 90 | * @return void |
92 | 91 | */ |
@@ -119,16 +118,16 @@ function () use ( $wp ) { |
119 | 118 | array_merge( $core_meta, array( 'freshness' => 'generated' ) ) |
120 | 119 | ); |
121 | 120 |
|
122 | | - // The reflected `datamachine` command-surface section. |
| 121 | + // Data Machine routing and discovery guidance. |
123 | 122 | SectionRegistry::register( |
124 | 123 | 'AGENTS.md', |
125 | 124 | 'datamachine', |
126 | 125 | 10, |
127 | 126 | 'datamachine_agents_md_render_datamachine_section', |
128 | 127 | array( |
129 | 128 | 'owner' => 'data-machine', |
130 | | - 'freshness' => 'snapshot', |
131 | | - 'conditions' => 'Registered when DATAMACHINE_COMPOSE_AGENTS_MD is enabled; command list reflected from registered command classes.', |
| 129 | + 'freshness' => 'static', |
| 130 | + 'conditions' => 'Registered when DATAMACHINE_COMPOSE_AGENTS_MD is enabled.', |
132 | 131 | ) |
133 | 132 | ); |
134 | 133 |
|
@@ -157,159 +156,30 @@ function () use ( $wp ) { |
157 | 156 | /** |
158 | 157 | * Render the `## Data Machine` AGENTS.md section. |
159 | 158 | * |
160 | | - * The command list is reflected from CommandRegistry::map() — the same map that |
161 | | - * feeds WP-CLI registration in Bootstrap.php — so adding or renaming a |
162 | | - * `datamachine` subcommand surfaces here automatically with no heredoc edit, and |
163 | | - * a command removed from core (e.g. the now-relocated `analytics`) disappears |
164 | | - * from the documentation by construction. |
| 159 | + * Persistent agent context carries ownership, routing, and discovery guidance. |
| 160 | + * The live WP-CLI help remains authoritative for the complete command map. |
165 | 161 | * |
166 | 162 | * @return string |
167 | 163 | */ |
168 | 164 | function datamachine_agents_md_render_datamachine_section(): string { |
169 | 165 | $wp = datamachine_agents_md_wp_cli_cmd(); |
170 | 166 |
|
171 | | - $lines = array(); |
172 | | - $lines[] = '## Data Machine'; |
173 | | - $lines[] = ''; |
174 | | - $lines[] = 'Data Machine is your operating layer — memory, automation, and orchestration via WP-CLI.'; |
175 | | - $lines[] = ''; |
176 | | - $lines[] = "Discover the full command surface: `{$wp} datamachine --help`. Always run `--help` on any subcommand to see its options."; |
177 | | - $lines[] = ''; |
| 167 | + return <<<MD |
| 168 | +## Data Machine |
178 | 169 |
|
179 | | - foreach ( datamachine_agents_md_command_groups() as $command => $subcommands ) { |
180 | | - $pipe = implode( '|', $subcommands ); |
| 170 | +Data Machine is the WordPress-side operating layer for memory, automation, content operations, communication, agent configuration, and system execution. |
181 | 171 |
|
182 | | - if ( '' !== $pipe ) { |
183 | | - $lines[] = "- `{$wp} {$command} {$pipe}`"; |
184 | | - } else { |
185 | | - $lines[] = "- `{$wp} {$command}`"; |
186 | | - } |
187 | | - } |
188 | | - |
189 | | - $lines[] = ''; |
190 | | - $lines[] = 'Use `--help` on any command to discover options and subcommands.'; |
191 | | - |
192 | | - return implode( "\n", $lines ); |
193 | | -} |
194 | | - |
195 | | -/** |
196 | | - * Build the ordered command => subcommand-names map for the section. |
197 | | - * |
198 | | - * Reflects each command class via the shared CliCommandIntrospector (preferred) |
199 | | - * and degrades to a local reflection fallback when the shared helper is |
200 | | - * unavailable or lacks the method. De-duplicates by class so singular/plural |
201 | | - * aliases that resolve to the same class document once, preserving the first |
202 | | - * registered spelling. |
203 | | - * |
204 | | - * @return array<string, string[]> Command label => ordered subcommand names. |
205 | | - */ |
206 | | -function datamachine_agents_md_command_groups(): array { |
207 | | - $groups = array(); |
208 | | - $seen = array(); |
209 | | - |
210 | | - foreach ( CommandRegistry::map() as $command => $command_class ) { |
211 | | - if ( isset( $seen[ $command_class ] ) ) { |
212 | | - continue; |
213 | | - } |
214 | | - $seen[ $command_class ] = true; |
215 | | - |
216 | | - $groups[ $command ] = datamachine_agents_md_subcommand_names( $command_class ); |
217 | | - } |
218 | | - |
219 | | - return $groups; |
220 | | -} |
221 | | - |
222 | | -/** |
223 | | - * Resolve a command class's subcommand names, preferring the shared helper. |
224 | | - * |
225 | | - * @param class-string $command_class Command class. |
226 | | - * @return string[] Ordered subcommand names ('__default' omitted). |
227 | | - */ |
228 | | -function datamachine_agents_md_subcommand_names( string $command_class ): array { |
229 | | - $introspector = '\\DataMachine\\Engine\\AI\\CliCommandIntrospector'; |
230 | | - |
231 | | - if ( class_exists( $introspector ) && method_exists( $introspector, 'describe_class' ) ) { |
232 | | - $subcommands = call_user_func( array( $introspector, 'describe_class' ), $command_class ); |
233 | | - $names = array(); |
234 | | - foreach ( (array) $subcommands as $sub ) { |
235 | | - $name = is_array( $sub ) ? ( $sub['name'] ?? '' ) : ''; |
236 | | - if ( '' === $name || '__default' === $name ) { |
237 | | - continue; |
238 | | - } |
239 | | - $names[] = $name; |
240 | | - } |
241 | | - |
242 | | - // describe_class returns [] for classes whose only subcommand is an |
243 | | - // __invoke (flat invoke commands) on helper versions that predate |
244 | | - // __invoke support (#2639). Fall back locally so those still document. |
245 | | - if ( ! empty( $names ) ) { |
246 | | - return $names; |
247 | | - } |
248 | | - } |
| 172 | +**Default routing** |
| 173 | +- Memory and composed context: `{$wp} datamachine memory --help` |
| 174 | +- Flows and pipelines: `{$wp} datamachine flows` and `{$wp} datamachine pipelines` |
| 175 | +- Job and worker state: `{$wp} datamachine jobs --help` and `{$wp} datamachine worker --help` |
| 176 | +- Content and media operations: `{$wp} datamachine posts --help`, `{$wp} datamachine blocks --help`, or `{$wp} datamachine image --help` |
| 177 | +- Communication and approval queues: `{$wp} datamachine email --help` and `{$wp} datamachine pending-actions --help` |
| 178 | +- Agent and system configuration: `{$wp} datamachine agent --help` and `{$wp} datamachine system --help` |
249 | 179 |
|
250 | | - return datamachine_agents_md_reflect_subcommand_names( $command_class ); |
251 | | -} |
252 | | - |
253 | | -/** |
254 | | - * Local reflection fallback for subcommand names. |
255 | | - * |
256 | | - * Context-safe: reflects over the class source without touching the live WP-CLI |
257 | | - * runner. Mirrors WP-CLI's subcommand resolution — public, non-static, |
258 | | - * own-declared methods; `@subcommand <name>` annotation wins over the method |
259 | | - * name; magic methods are skipped except `__invoke`, which maps to the namespace |
260 | | - * itself ('__default') and is therefore omitted from the documented list. |
261 | | - * |
262 | | - * @param class-string $command_class Command class. |
263 | | - * @return string[] Ordered subcommand names. |
264 | | - */ |
265 | | -function datamachine_agents_md_reflect_subcommand_names( string $command_class ): array { |
266 | | - if ( ! class_exists( $command_class ) ) { |
267 | | - return array(); |
268 | | - } |
269 | | - |
270 | | - try { |
271 | | - $reflection = new \ReflectionClass( $command_class ); |
272 | | - } catch ( \Throwable $e ) { |
273 | | - return array(); |
274 | | - } |
275 | | - |
276 | | - $names = array(); |
277 | | - |
278 | | - foreach ( $reflection->getMethods( \ReflectionMethod::IS_PUBLIC ) as $method ) { |
279 | | - if ( $method->isStatic() ) { |
280 | | - continue; |
281 | | - } |
282 | | - if ( $method->getDeclaringClass()->getName() !== $reflection->getName() ) { |
283 | | - continue; |
284 | | - } |
285 | | - |
286 | | - $method_name = $method->getName(); |
287 | | - $doc = $method->getDocComment(); |
288 | | - $doc = is_string( $doc ) ? $doc : ''; |
289 | | - |
290 | | - $annotated = ''; |
291 | | - if ( preg_match( '/@subcommand\s+(\S+)/', $doc, $m ) ) { |
292 | | - $annotated = $m[1]; |
293 | | - } |
294 | | - |
295 | | - if ( '__invoke' === $method_name && '' === $annotated ) { |
296 | | - // Flat invoke command — the namespace itself, no sub-word. |
297 | | - continue; |
298 | | - } |
299 | | - |
300 | | - if ( '' !== $annotated ) { |
301 | | - $names[] = $annotated; |
302 | | - continue; |
303 | | - } |
304 | | - |
305 | | - if ( 0 === strpos( $method_name, '__' ) ) { |
306 | | - continue; |
307 | | - } |
308 | | - |
309 | | - $names[] = str_replace( '_', '-', $method_name ); |
310 | | - } |
311 | | - |
312 | | - return $names; |
| 180 | +**Discovery** |
| 181 | +Use `{$wp} datamachine --help` for the live command map and `{$wp} datamachine <command> --help` for the current options and subcommands. |
| 182 | +MD; |
313 | 183 | } |
314 | 184 |
|
315 | 185 | /** |
|
0 commit comments