Skip to content

Commit 78500cb

Browse files
author
Test
committed
[docs] Add comprehensive architecture documentation for giv CLI
1 parent fc65826 commit 78500cb

File tree

1 file changed

+288
-0
lines changed

1 file changed

+288
-0
lines changed

docs/architecture.md

Lines changed: 288 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,288 @@
1+
# Architecture
2+
3+
A quick overview: giv is a POSIX-compliant shell script suite whose main entrypoint (giv.sh) initializes environment and dispatches subcommands. It sources modular libraries for configuration, system utilities, argument parsing, Markdown handling, LLM integration, project metadata, history extraction, and subcommand implementations. Major workflows include commit summarization (via summarize\_commit), changelog generation (cmd\_changelog), release-notes and announcements (via cmd\_document), and a generic document driver. Data domains span Git metadata (commits, diffs, tags), project metadata (version files, project titles), AI prompt templates, and generated summaries. Caching under `.giv/cache` avoids redundant work. Below are the details.
4+
5+
## Repository Structure
6+
7+
### Script Entry Point
8+
9+
The main script, **giv.sh**, locates the library, template, and docs directories, sources all helper modules, parses arguments, and dispatches to subcommands like `message`, `summary`, `changelog`, `release-notes`, `announcement`, `document`, and maintenance commands (`init`, `update`) ([giv.sh][1]).
10+
11+
### Configuration Module
12+
13+
**config.sh** exports globals for version (`__VERSION`), directory paths (`GIV_HOME`, `GIV_TMP_DIR`, `GIV_CACHE_DIR`), debugging flags, default Git revision/pathspec, AI model and API settings, project tokens, and default output filenames (`CHANGELOG.md`, etc.) ([config.sh][2]).
14+
15+
### System Utilities
16+
17+
**system.sh** provides logging functions (`print_debug`, `print_info`, etc.), temporary-dir management (`portable_mktemp_dir`, `remove_tmp_dir`), `.giv` directory initialization (`ensure_giv_dir_init`), and location helpers (`find_giv_dir`) ([system.sh][3]).
18+
19+
### Argument Parsing
20+
21+
**args.sh** defines `show_help` and `parse_args`, mapping CLI options to `GIV_*` variables, validating revisions/pathspecs, handling config files early, and configuring local vs remote AI modes ([args.sh][4]).
22+
23+
### Markdown Handling
24+
25+
**markdown.sh** implements `manage_section` for append/prepend/update of Markdown sections, `append_link` to add links, utilities for stripping and normalizing Markdown (`strip_markdown`, `normalize_blank_lines`), and Markdown viewing via `glow` ([markdown.sh][5]).
26+
27+
### LLM Integration
28+
29+
**llm.sh** handles JSON-escaping (`json_escape`), remote API calls (`generate_remote` via curl), local inference (`run_local` via Ollama), response parsing (`extract_content_from_response`), and high-level `generate_response`, along with prompt token replacement (`replace_tokens`), prompt building (`build_prompt`), and execution (`generate_from_prompt`) ([llm.sh][6]).
30+
31+
### Project Metadata
32+
33+
**project.sh** extracts project titles and version information from common project files like `package.json`, `pyproject.toml`, and `setup.py`. It also supports custom version file detection ([project.sh][7]).
34+
35+
### History Extraction
36+
37+
**history.sh** provides utilities for summarizing Git history, extracting TODO changes, and caching summaries ([history.sh][8]).
38+
39+
### Subcommand Implementations
40+
41+
**commands.sh** ties everything into user-facing commands: `cmd_message` for AI draft commit messages, `cmd_changelog` for changelog updates (using `manage_section`), `cmd_document` as a generic driver for release-notes, announcements, custom docs, and maintenance commands (`show_version`, `get_available_releases`, `run_update`) ([commands.sh][9]).
42+
43+
## Data Domains
44+
45+
1. **Git Data**: Commits, diffs, staged/unstaged changes, untracked files, commit dates, tags and ranges (handled by `build_diff`, `get_commit_date`, Git plumbing) ([history.sh][8]).
46+
2. **Project Metadata**: Version files (`package.json`, etc.), extracted versions (`get_version_info`), and project titles (`get_project_title`) ([project.sh][7]).
47+
3. **AI Prompt Templates**: Markdown templates stored under `templates/` (e.g. `summary_prompt.md`, `changelog_prompt.md`, `release_notes_prompt.md`, `announcement_prompt.md`) ([giv.sh][1]).
48+
4. **Generated Content**: Summary Markdown, commit messages, changelogs, release notes, announcements, managed under `.giv/cache` and output files in project root ([system.sh][3]) ([history.sh][8]).
49+
5. **Configuration & State**: Stored in `.giv/config`, `.giv/cache`, `.giv/.tmp`, and optionally `.giv/templates` (after `init`) ([system.sh][3]).
50+
51+
## Workflows
52+
53+
### Commit Summarization
54+
55+
The `summarize_commit` function in **history.sh** orchestrates:
56+
57+
1. Generating raw history with `build_history`.
58+
2. Finding version info via `get_version_info`.
59+
3. Building an AI prompt (`build_prompt` with `summary_prompt.md`).
60+
4. Generating the summary (`generate_response`).
61+
Caching ensures repeated calls skip regeneration ([history.sh][8], [llm.sh][6]).
62+
63+
### Changelog Generation
64+
65+
`cmd_changelog` in **commands.sh** follows:
66+
67+
1. Summarize commits/ranges with `summarize_target`.
68+
2. Build the changelog prompt (`changelog_prompt.md`) via `build_prompt`.
69+
3. Generate content (`generate_from_prompt`).
70+
4. Update `CHANGELOG.md` using `manage_section` and append a “Managed by giv” link ([commands.sh][9]).
71+
72+
### Release-Notes & Announcements
73+
74+
Both use the generic `cmd_document` driver:
75+
76+
1. Summarize history into temp file.
77+
2. Build prompt from `release_notes_prompt.md` or `announcement_prompt.md`.
78+
3. Call `generate_from_prompt` with tailored temperature and context window ([giv.sh][1]).
79+
4. Output to `RELEASE_NOTES.md` or `ANNOUNCEMENT.md`.
80+
81+
### Generic Document Generation
82+
83+
The `document` subcommand invokes `cmd_document` with a user-supplied `--prompt-file`, enabling arbitrary AI-driven reports over any revision/pathspec ([commands.sh][9]).
84+
85+
## Architecture Diagrams
86+
87+
### Sequence Diagram
88+
89+
```mermaid
90+
sequenceDiagram
91+
participant User
92+
participant giv.sh
93+
participant Args as args.sh
94+
participant History as history.sh
95+
participant LLM as llm.sh
96+
participant Markdown as markdown.sh
97+
participant Output
98+
99+
User->>giv.sh: runs `giv changelog v1.2.0..HEAD`
100+
giv.sh->>Args: parse_args(...)
101+
Args-->>giv.sh: globals set
102+
giv.sh->>History: summarize_target(...)
103+
History-->>History: build_history(...)
104+
History->>LLM: build_prompt + generate_response
105+
LLM-->>History: AI summary
106+
History-->>giv.sh: summaries file
107+
giv.sh->>Markdown: manage_section(...)
108+
Markdown-->>giv.sh: updated Markdown
109+
giv.sh->>Output: write CHANGELOG.md
110+
```
111+
112+
### Class Diagram
113+
114+
```mermaid
115+
classDiagram
116+
class giv.sh {
117+
+get_script_dir()
118+
+parse_args()
119+
+dispatch()
120+
}
121+
class config.sh {
122+
- export GIV_*
123+
}
124+
class system.sh {
125+
+print_debug()
126+
+portable_mktemp_dir()
127+
+ensure_giv_dir_init()
128+
}
129+
class args.sh {
130+
+parse_args()
131+
+show_help()
132+
}
133+
class markdown.sh {
134+
+manage_section()
135+
+append_link()
136+
}
137+
class llm.sh {
138+
+generate_response()
139+
+build_prompt()
140+
}
141+
class project.sh {
142+
+get_project_title()
143+
+get_version_info()
144+
}
145+
class history.sh {
146+
+build_history()
147+
+summarize_commit()
148+
}
149+
class commands.sh {
150+
+cmd_changelog()
151+
+cmd_document()
152+
+cmd_message()
153+
}
154+
155+
giv.sh --> config.sh
156+
giv.sh --> system.sh
157+
giv.sh --> args.sh
158+
giv.sh --> markdown.sh
159+
giv.sh --> llm.sh
160+
giv.sh --> project.sh
161+
giv.sh --> history.sh
162+
giv.sh --> commands.sh
163+
commands.sh --> history.sh
164+
commands.sh --> llm.sh
165+
commands.sh --> markdown.sh
166+
history.sh --> project.sh
167+
llm.sh --> project.sh
168+
markdown.sh --> system.sh
169+
```
170+
171+
This should give you a clear view of how the scripts interconnect, the data each component handles, and the flow of execution through the tool.
172+
173+
[1]: /src/giv.sh "giv.sh"
174+
[2]: /src/config.sh "config.sh"
175+
[3]: /src/system.sh "system.sh"
176+
[4]: /src/args.sh "args.sh"
177+
[5]: /src/markdown.sh "markdown.sh"
178+
[6]: /src/llm.sh
179+
[7]: /src/project.sh
180+
[8]: /src/history.sh
181+
[9]: /src/commands.sh
182+
183+
Across the giv-CLI tool, there are five primary **data domains**—each holding specific values—and the `document` subcommand orchestrates several modules in a well-defined call sequence. Below is a data-structure diagram showing the domains and their key contents, then a detailed sequence diagram illustrating exactly how `giv document` runs under the hood.
184+
185+
---
186+
187+
## Data Domains and Their Contents
188+
189+
```mermaid
190+
classDiagram
191+
%% Data Domains
192+
class GitData {
193+
+commits: List<Commit SHA>
194+
+diffs: Unified diff text
195+
+pathspec: String
196+
+tags: List<String>
197+
+revisionRange: String
198+
}
199+
class ProjectMetadata {
200+
+projectTitle: String
201+
+version: String
202+
+versionFile: File path
203+
}
204+
class PromptTemplates {
205+
+name: String
206+
+templateFile: Path
207+
+tokens: Map<String,String>
208+
}
209+
class GeneratedContent {
210+
+summary: Markdown text
211+
+changelog: Markdown text
212+
+releaseNotes: Markdown text
213+
+announcement: Markdown text
214+
}
215+
class ConfigState {
216+
+GIV_HOME: Path
217+
+CACHE_DIR: Path
218+
+TMP_DIR: Path
219+
+DEBUG: Boolean
220+
+MODEL: String
221+
+API_KEY: String
222+
}
223+
224+
%% Relationships
225+
ConfigState --> GitData : configures
226+
ConfigState --> PromptTemplates : points to
227+
GitData <--> GeneratedContent : source for
228+
ProjectMetadata <--> GeneratedContent : metadata in
229+
PromptTemplates <-- GeneratedContent : drives format
230+
```
231+
232+
* **GitData**: all raw Git artifacts (commits, diffs, tags, revision ranges, pathspecs) used to build histories and summaries.
233+
* **ProjectMetadata**: extracted from files like `package.json` or `pyproject.toml`—contains project title and version info.
234+
* **PromptTemplates**: stored under `templates/`, each named (e.g. `summary_prompt.md`, `changelog_prompt.md`, `document_prompt.md`) with substitution tokens.
235+
* **GeneratedContent**: the AI-produced Markdown blobs (commit messages, changelogs, release notes, documents, announcements).
236+
* **ConfigState**: CLI configuration and state in `.giv/` (home, cache, temp dirs), debug flags, AI model choice, API credentials.
237+
238+
---
239+
240+
## Sequence of `giv document --prompt-file <file> <range>`
241+
242+
```mermaid
243+
sequenceDiagram
244+
participant User
245+
participant giv.sh
246+
participant args.sh
247+
participant system.sh
248+
participant history.sh
249+
participant project.sh
250+
participant llm.sh
251+
participant markdown.sh
252+
participant OutputFile as "DOCUMENT.md"
253+
254+
User->>giv.sh: "giv document --prompt-file templates/document_prompt.md v1.2.0..HEAD"
255+
alt First time after cloning
256+
giv.sh->>system.sh: ensure_giv_dir_init()
257+
system.sh-->>giv.sh: .giv/ dirs created
258+
end
259+
giv.sh->>args.sh: parse_args(...)
260+
args.sh-->>giv.sh: set GIV_PROMPT_FILE, GIV_REV_RANGE, etc.
261+
262+
giv.sh->>history.sh: summarize_target("v1.2.0..HEAD")
263+
history.sh->>history.sh: build_history("v1.2.0..HEAD")
264+
history.sh->>project.sh: get_project_title()
265+
project.sh-->>history.sh: "My Project"
266+
history.sh->>project.sh: get_version_info("v1.2.0")
267+
project.sh-->>history.sh: "1.2.0"
268+
269+
history.sh->>llm.sh: build_prompt(templates/document_prompt.md,history.md,title, version)
270+
llm.sh-->>history.sh: fullPrompt
271+
history.sh->>llm.sh: generate_response(fullPrompt)
272+
llm.sh-->>history.sh: aiDocumentContent.md
273+
274+
history.sh-->>giv.sh: /tmp/giv_document_output.md
275+
giv.sh->>markdown.sh: write_output(/tmp/giv_document_output.md,"DOCUMENT.md")
276+
markdown.sh-->>giv.sh: DOCUMENT.md written
277+
278+
giv.sh->>OutputFile: display("DOCUMENT.md")
279+
```
280+
281+
1. **Initialization** (once): creates `.giv/` directories.
282+
2. **Argument Parsing**: `args.sh` sets up global vars (prompt file, revision range).
283+
3. **History Extraction**: `history.sh` builds a unified history for the given range, invoking `project.sh` for title/version.
284+
4. **Prompt Assembly**: `llm.sh` merges the template, history, and metadata into a single prompt.
285+
5. **AI Generation**: same module calls out to remote/local LLM, returns the document text.
286+
6. **Output**: `markdown.sh` writes the result to `DOCUMENT.md` and the CLI presents it.
287+
288+
These diagrams and explanations should give you a clear map of **what data lives where** and **how the `document` flow unfolds** end-to-end.

0 commit comments

Comments
 (0)