Skip to content

Commit 728aee4

Browse files
mjwolfclaude
andcommitted
Add AI-powered documentation update command
Introduce a new `elastic-package update documentation` command that leverages LLM providers to automatically generate and update package documentation. Key features: - Two operation modes: * Rewrite mode: Full documentation regeneration from package structure * Modify mode: Targeted changes to existing documentation - Multi-file support: Update any markdown file in _dev/build/docs/ - Interactive and non-interactive workflows - Provider flexibility: Support for Gemini API and local LLM servers Implementation details: - Add new LLM framework in internal/llmagent/ with: * Provider abstraction for different LLM backends * Documentation agent with package analysis tools * MCP (Model Context Protocol) tools integration * Interactive UI with browser-based markdown preview - Configuration via environment variables or profile config - Graceful degradation: Show manual update instructions when no provider configured Command flags: - --non-interactive: Skip prompts and auto-accept first result - --modify-prompt: Specify targeted modification instructions - --doc-file: Select specific markdown file to update This enables maintainers to quickly generate comprehensive, template-compliant documentation by analyzing package structure, data streams, and configuration. Co-Authored-By: Jonathan Molinatto <[email protected]> Co-Authored-By: Claude <[email protected]> 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <[email protected]>
1 parent b6d9256 commit 728aee4

34 files changed

+4135
-12
lines changed

README.md

Lines changed: 149 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -638,6 +638,53 @@ Use this command to uninstall the package in Kibana.
638638

639639
The command uses Kibana API to uninstall the package in Kibana. The package must be exposed via the Package Registry.
640640

641+
### `elastic-package update`
642+
643+
_Context: global_
644+
645+
Use this command to update package resources.
646+
647+
The command can help update existing resources in a package. Currently only documentation is supported.
648+
649+
### `elastic-package update documentation`
650+
651+
_Context: global_
652+
653+
Use this command to update package documentation using an AI agent or to get manual instructions for update.
654+
655+
The AI agent supports two modes:
656+
1. Rewrite mode (default): Full documentation regeneration
657+
- Analyzes your package structure, data streams, and configuration
658+
- Generates comprehensive documentation following Elastic's templates
659+
- Creates or updates markdown files in /_dev/build/docs/
660+
2. Modify mode: Targeted documentation changes
661+
- Makes specific changes to existing documentation
662+
- Requires existing documentation file at /_dev/build/docs/
663+
- Use --modify-prompt flag for non-interactive modifications
664+
665+
Multi-file support:
666+
- Use --doc-file to specify which markdown file to update (defaults to README.md)
667+
- In interactive mode, you'll be prompted to select from available files
668+
- Supports packages with multiple documentation files (e.g., README.md, vpc.md, etc.)
669+
670+
Interactive workflow:
671+
After confirming you want to use the AI agent, you'll choose between rewrite or modify mode.
672+
You can review results and request additional changes iteratively.
673+
674+
Non-interactive mode:
675+
Use --non-interactive to skip all prompts and automatically accept the first result from the LLM.
676+
Combine with --modify-prompt "instructions" for targeted non-interactive changes.
677+
678+
If no LLM provider is configured, this command will print instructions for updating the documentation manually.
679+
680+
Configuration options for LLM providers (environment variables or profile config):
681+
- GEMINI_API_KEY / llm.gemini.api_key: API key for Gemini
682+
- GEMINI_MODEL / llm.gemini.model: Model ID (defaults to gemini-2.5-pro)
683+
- LOCAL_LLM_ENDPOINT / llm.local.endpoint: Endpoint for local LLM server
684+
- LOCAL_LLM_MODEL / llm.local.model: Model name for local LLM (defaults to llama2)
685+
- LOCAL_LLM_API_KEY / llm.local.api_key: API key for local LLM (optional)
686+
- LLM_EXTERNAL_PROMPTS / llm.external_prompts: Enable external prompt files (defaults to false).
687+
641688
### `elastic-package version`
642689

643690
_Context: global_
@@ -690,6 +737,101 @@ The following settings are available per profile:
690737
Currently, it is supported "basic" and "[trial](https://www.elastic.co/guide/en/elasticsearch/reference/current/start-trial.html)",
691738
which enables all subscription features for 30 days. Defaults to "trial".
692739

740+
### AI-powered Documentation Configuration
741+
742+
The `elastic-package update documentation` command supports AI-powered documentation generation using various LLM providers.
743+
744+
**⚠️ IMPORTANT PRIVACY NOTICE:**
745+
When using AI-powered documentation generation, **file content from your local file system within the package directory may be sent to the configured LLM provider**. This includes manifest files, configuration files, field definitions, and other package content. The generated documentation **must be reviewed for accuracy and correctness** before being finalized, as LLMs may occasionally produce incorrect or hallucinated information.
746+
747+
#### Operation Modes
748+
749+
The command supports two modes of operation:
750+
751+
1. **Rewrite Mode** (default): Full documentation regeneration
752+
- Analyzes your package structure, data streams, and configuration
753+
- Generates comprehensive documentation following Elastic's templates
754+
- Creates or updates the README.md file in `/_dev/build/docs/`
755+
756+
2. **Modify Mode**: Targeted documentation changes
757+
- Makes specific changes to existing documentation
758+
- Requires existing README.md file at `/_dev/build/docs/README.md`
759+
- Use `--modify-prompt` flag for non-interactive modifications
760+
761+
#### Workflow Options
762+
763+
**Interactive Mode** (default):
764+
The command will guide you through the process, allowing you to:
765+
- Choose between rewrite or modify mode
766+
- Review generated documentation
767+
- Request iterative changes
768+
- Accept or cancel the update
769+
770+
**Non-Interactive Mode**:
771+
Use `--non-interactive` to skip all prompts and automatically accept the first result.
772+
Combine with `--modify-prompt "instructions"` for targeted non-interactive changes.
773+
774+
If no LLM provider is configured, the command will print manual instructions for updating documentation.
775+
776+
#### LLM Provider Configuration
777+
778+
You can configure LLM providers through **profile settings** (in `~/.elastic-package/profiles/<profile>/config.yml`) as an alternative to environment variables:
779+
780+
* `llm.gemini.api_key`: API key for Google Gemini LLM services
781+
* `llm.gemini.model`: Gemini model ID (defaults to `gemini-2.5-pro`)
782+
* `llm.local.endpoint`: Endpoint URL for local OpenAI-compatible LLM servers
783+
* `llm.local.model`: Model name for local LLM servers (defaults to `llama2`)
784+
* `llm.local.api_key`: API key for local LLM servers (optional, if authentication is required)
785+
* `llm.external_prompts`: Enable loading custom prompt files from profile or data directory (defaults to `false`)
786+
787+
Environment variables (e.g., `GEMINI_API_KEY`, `LOCAL_LLM_ENDPOINT`) take precedence over profile configuration.
788+
789+
#### Usage Examples
790+
791+
```bash
792+
# Interactive documentation update (rewrite mode)
793+
elastic-package update documentation
794+
795+
# Interactive modification mode
796+
elastic-package update documentation
797+
# (choose "Modify" when prompted)
798+
799+
# Non-interactive rewrite
800+
elastic-package update documentation --non-interactive
801+
802+
# Non-interactive targeted changes
803+
elastic-package update documentation --modify-prompt "Add more details about authentication configuration"
804+
805+
# Use specific profile with LLM configuration
806+
elastic-package update documentation --profile production
807+
```
808+
809+
#### Advanced Features
810+
811+
**Preserving Human-Edited Content:**
812+
813+
Manually edited sections can be preserved by wrapping them with HTML comment markers:
814+
815+
```html
816+
<!-- PRESERVE START -->
817+
Important manual content to preserve
818+
<!-- PRESERVE END -->
819+
```
820+
821+
Any content between these markers will be preserved exactly as-is during AI-generated documentation updates. The system will automatically validate preservation after generation and warn if marked content was modified or removed.
822+
823+
**Service Knowledge Base:**
824+
825+
Place a `docs/knowledge_base/service_info.md` file in your package to provide authoritative service information. This file is treated as the source of truth and takes precedence over web search results during documentation generation.
826+
827+
**Custom Prompts:**
828+
829+
Enable `llm.external_prompts` in your profile config to use custom prompt files. Place them in:
830+
- `~/.elastic-package/profiles/<profile>/prompts/` (profile-specific)
831+
- `~/.elastic-package/prompts/` (global)
832+
833+
Available prompt files: `initial_prompt.txt`, `revision_prompt.txt`, `limit_hit_prompt.txt`
834+
693835
## Useful environment variables
694836

695837
There are available some environment variables that could be used to change some of the
@@ -747,6 +889,13 @@ There are available some environment variables that could be used to change some
747889
- `ELASTIC_PACKAGE_ESMETRICSTORE_PASSWORD`: Password for the user.
748890
- `ELASTIC_PACKAGE_ESMETRICSTORE_CA_CERT`: Path to the CA certificate to connect to the Elastic stack services.
749891

892+
- To configure LLM providers for AI-powered documentation generation (`elastic-package update documentation`):
893+
- `GEMINI_API_KEY`: API key for Gemini LLM services
894+
- `GEMINI_MODEL`: Gemini model ID (defaults to `gemini-2.5-pro`)
895+
- `LOCAL_LLM_ENDPOINT`: Endpoint URL for local OpenAI-compatible LLM servers.
896+
- `LOCAL_LLM_MODEL`: Model name for local LLM servers (defaults to `llama2`)
897+
- `LOCAL_LLM_API_KEY`: API key for local LLM servers (optional, if authentication is required)
898+
750899

751900
## Release process
752901

cmd/root.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ var commands = []*cobraext.Command{
3737
setupStatusCommand(),
3838
setupTestCommand(),
3939
setupUninstallCommand(),
40+
setupUpdateCommand(),
4041
setupVersionCommand(),
4142
}
4243

cmd/update.go

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
// Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
2+
// or more contributor license agreements. Licensed under the Elastic License;
3+
// you may not use this file except in compliance with the Elastic License.
4+
5+
package cmd
6+
7+
import (
8+
"fmt"
9+
10+
"github.com/spf13/cobra"
11+
12+
"github.com/elastic/elastic-package/internal/cobraext"
13+
"github.com/elastic/elastic-package/internal/install"
14+
)
15+
16+
const updateLongDescription = `Use this command to update package resources.
17+
18+
The command can help update existing resources in a package. Currently only documentation is supported.`
19+
20+
func setupUpdateCommand() *cobraext.Command {
21+
updateDocumentationCmd := &cobra.Command{
22+
Use: "documentation",
23+
Short: "Update package documentation",
24+
Long: updateDocumentationLongDescription,
25+
Args: cobra.NoArgs,
26+
RunE: updateDocumentationCommandAction,
27+
}
28+
updateDocumentationCmd.Flags().Bool("non-interactive", false, "run in non-interactive mode, accepting the first result from the LLM")
29+
updateDocumentationCmd.Flags().String("modify-prompt", "", "modification instructions for targeted documentation changes (skips full rewrite)")
30+
updateDocumentationCmd.Flags().String("doc-file", "", "specify which markdown file to update (e.g., README.md, vpc.md). Defaults to README.md")
31+
32+
cmd := &cobra.Command{
33+
Use: "update",
34+
Short: "Update package resources",
35+
Long: updateLongDescription,
36+
}
37+
cmd.AddCommand(updateDocumentationCmd)
38+
cmd.PersistentFlags().StringP(cobraext.ProfileFlagName, "p", "", fmt.Sprintf(cobraext.ProfileFlagDescription, install.ProfileNameEnvVar))
39+
40+
return cobraext.NewCommand(cmd, cobraext.ContextGlobal)
41+
}

0 commit comments

Comments
 (0)