Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
57 changes: 47 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,10 @@ task build

```
./bauer --doc-id <doc-id> \
--credentials <path-to-creds> \
--parse-only
--credentials <path-to-creds>
--github-repo <github-repo>
```
Comment thread
britneywwc marked this conversation as resolved.
Comment on lines 24 to 27
Additionally, you can run it with `--parse-only` without creeting an issue.


## Configuration
Expand All @@ -39,27 +40,55 @@ cp credentials.example.json credentials.json
## Usage

1. Build Bauer locally using the Local development steps above (`task build`)
2. If running with GitHub integration (no `--parse-only`), ensure `copilot` is installed and authenticated
2. If running with GitHub issue creation (no `--parse-only`), ensure GitHub CLI auth is available
Comment on lines 42 to +43
3. Get document ID from Google Document & share the document with the service account
4. Run Bauer

### GitHub CLI authentication

Run these once before using parse-and-issue mode:

```bash
gh auth login
gh auth status
```

If you prefer token auth in non-interactive environments:

```bash
export GH_TOKEN=<your_token>
gh auth status
```

```bash
./bauer --doc-id <your-document-id> --credentials ./credentials.json
```

5. Optional parameters

| Flag | Type | Default | Description | Requires Copilot |
| ------------------ | ------ | -------------------- | ------------------------------------------------------------------------------- | ---------------- |
| Flag | Type | Default | Description | Requires GitHub Auth |
| ------------------ | ------ | -------------------- | ------------------------------------------------------------------------------- | -------------------- |
| `--github-repo` | string | (required if not parse-only) | GitHub repository (owner/repo or HTTPS URL) | Yes* |
| `--credentials` | string | `bau-test-creds.json` | Path to service account credentials JSON | No |
| `--local-repo-path` | string | `/tmp/ubuntu.com` | Local path for cloned repository | No |
| `--dry-run` | bool | `false` | Perform a dry run without creating PR | Yes* |
| `--output-dir` | string | `bauer-output` | Output directory for Bauer results | No |
| `--branch-prefix` | string | `bauer` | Branch naming prefix | No |
| `--parse-only` | bool | `false` | Parse document and output machine-readable JSON (skip GitHub integration) | No |
| `--parse-only` | bool | `false` | Parse document and output machine-readable JSON only | No |

Current execution modes:

1. Parse-only mode (`--parse-only`)
- Creates `bauer-output/bauer-parse-result.json`
- Does not push branches
- Does not create issues

2. Parse-and-issue mode (without `--parse-only`)
- Creates `bauer-output/bauer-parse-result.json`
- Creates a branch and pushes the parse file into that branch
- Opens a GitHub issue assigned to Copilot (with fallbacks) and includes branch/pinned/raw links to the prompt file

*GitHub auth is only required when using parse-and-issue mode.

*These flags require Copilot integration to be configured when performing GitHub operations (not needed for `--parse-only`)
<!-- ### Examples

#### Basic run
Expand All @@ -68,12 +97,20 @@ cp credentials.example.json credentials.json
bauer --doc-id <your-document-id> --credentials ./credentials.json
```

#### Dry run (test without executing changes)
#### Parse only

```bash
bauer --doc-id <your-document-id> \
--credentials ./credentials.json \
--parse-only
```

#### Parse and create issue

```bash
bauer --doc-id <your-document-id> \
--credentials ./credentials.json \
--dry-run
--github-repo owner/repo
```

#### Custom chunk size and output directory
Expand Down
14 changes: 0 additions & 14 deletions cmd/app/types/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,6 @@ type APIConfig struct {
// Default is "bauer-output" if not specified.
BaseOutputDir string

// Model is the Copilot model to use for sessions.
// Default is "gpt-5-mini-high" if not specified.
Model string

// SummaryModel is the Copilot model to use for the summary session.
// Default is "gpt-5-mini-high" if not specified.
SummaryModel string

// TargetRepo is the path (relative or absolute) to the target repository
// where tasks should be executed. If not specified, uses the current directory.
TargetRepo string `json:"target_repo"`
Expand All @@ -30,8 +22,6 @@ type APIConfig struct {
func LoadConfig() (*APIConfig, error) {
credentialsPath := flag.String("credentials", "", "Path to service account JSON (required)")
baseOutputDir := flag.String("base-output-dir", "bauer-output", "Base path of directory for generated prompt files (default: bauer-output)")
model := flag.String("model", "gpt-5-mini-high", "Copilot model to use for sessions (default: gpt-5-mini-high)")
summaryModel := flag.String("summary-model", "gpt-5-mini-high", "Copilot model to use for summary session (default: gpt-5-mini-high)")
configFile := flag.String("config", "", "Path to JSON config file")
targetRepo := flag.String("target-repo", "", "Path to target repository where tasks should be executed (default: current directory)")

Expand All @@ -45,8 +35,6 @@ func LoadConfig() (*APIConfig, error) {
return &APIConfig{
CredentialsPath: cfg.CredentialsPath,
BaseOutputDir: cfg.OutputDir,
Model: cfg.Model,
SummaryModel: cfg.SummaryModel,
TargetRepo: cfg.TargetRepo,
}, nil
}
Expand All @@ -59,8 +47,6 @@ func LoadConfig() (*APIConfig, error) {
cfg := &APIConfig{
CredentialsPath: *credentialsPath,
BaseOutputDir: *baseOutputDir,
Model: *model,
SummaryModel: *summaryModel,
TargetRepo: *targetRepo,
}

Expand Down
2 changes: 0 additions & 2 deletions cmd/app/v1/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,6 @@ func JobPost(rc types.RouteConfig) func(w http.ResponseWriter, r *http.Request)
PageRefresh: payload.PageRefresh,
CredentialsPath: rc.APIConfig.CredentialsPath,
OutputDir: fmt.Sprintf("%s/%s", rc.APIConfig.BaseOutputDir, requestID),
Model: rc.APIConfig.Model,
SummaryModel: rc.APIConfig.SummaryModel,
}

go executeJob(requestID, cfg, rc)
Expand Down
9 changes: 4 additions & 5 deletions cmd/bauer/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,7 @@ func main() {
docID := flag.String("doc-id", "", "Google Doc ID")
credentialsPath := flag.String("credentials", "bau-test-creds.json", "Path to service account credentials JSON")
localRepoPath := flag.String("local-repo-path", "/tmp/ubuntu.com", "Local path for cloned repository")
dryRun := flag.Bool("dry-run", false, "Perform a dry run without creating PR")
parseOnly := flag.Bool("parse-only", false, "Phase 1: Parse document and output machine-readable JSON (skip GitHub integration)")
parseOnly := flag.Bool("parse-only", false, "Parse document and output machine-readable JSON only")
outputDir := flag.String("output-dir", "bauer-output", "Output directory for Bauer results")
branchPrefix := flag.String("branch-prefix", "bauer", "Branch naming prefix")

Expand All @@ -43,7 +42,7 @@ func main() {

// Create workflow input from CLI flags/config
ghToken := ""
if !*parseOnly {
if *githubRepo != "" {
var err error
ghToken, err = github.GetGitHubToken()
if err != nil {
Expand All @@ -58,7 +57,6 @@ func main() {
DocID: *docID,
Credentials: *credentialsPath,
LocalRepoPath: *localRepoPath,
DryRun: *dryRun,
ParseOnly: *parseOnly,
OutputDir: *outputDir,
}
Expand All @@ -78,7 +76,8 @@ func main() {
fmt.Printf("Output file: %s\n", result.OutputFile)
} else {
fmt.Printf("Status: %s\n", result.Status)
fmt.Printf("Output file: %s\n", result.OutputFile)
fmt.Printf("Branch: %s\n", result.RepositoryInfo.BranchName)
fmt.Printf("PR: %s\n", result.FinalizationInfo.PullRequest.URL)
fmt.Printf("Issue: %s\n", result.FinalizationInfo.Issue.URL)
}
}
13 changes: 0 additions & 13 deletions credentials.example.json

This file was deleted.

7 changes: 7 additions & 0 deletions google-credentials-example.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"type": "service_account",
"project_id": "",
"private_key": "",
"client_email": "",
"token_uri": ""
}
12 changes: 3 additions & 9 deletions internal/config/cli.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,10 @@ func Load() (*Config, error) {
docID := flag.String("doc-id", "", "Google Doc ID to extract feedback from (required)")
credentialsPath := flag.String("credentials", "", "Path to service account JSON (required)")
configFile := flag.String("config", "", "Path to JSON config file")
dryRun := flag.Bool("dry-run", false, "Run extraction and planning only; skip Copilot and PR creation")
parseOnly := flag.Bool("parse-only", false, "Parse document to JSON only; skip GitHub integration")
chunkSize := flag.Int("chunk-size", 0, "Total number of chunks to create (default: 1, or 5 if --page-refresh is set)")
pageRefresh := flag.Bool("page-refresh", false, "Use page refresh mode with page-refresh-instructions template (default chunk size: 5)")
outputDir := flag.String("output-dir", "bauer-output", "Directory for generated prompt files (default: bauer-output)")
model := flag.String("model", "gpt-5-mini-high", "Copilot model to use for sessions (default: gpt-5-mini-high)")
summaryModel := flag.String("summary-model", "gpt-5-mini-high", "Copilot model to use for summary session (default: gpt-5-mini-high)")
targetRepo := flag.String("target-repo", "", "Path to target repository where tasks should be executed (default: current directory)")

// Custom usage message
Expand All @@ -40,12 +38,10 @@ func Load() (*Config, error) {
{"--config", "<string>", "Path to JSON config file"},
{"--doc-id", "<string>", "Google Doc ID to extract feedback from (required)"},
{"--credentials", "<string>", "Path to service account JSON (required)"},
{"--dry-run", "", "Run extraction and planning only; skip Copilot and PR creation"},
{"--parse-only", "", "Parse document to JSON only; skip GitHub integration"},
{"--page-refresh", "", "Use page refresh mode with page-refresh-instructions template"},
{"--chunk-size", "<int>", "Total number of chunks to create (default: 1, or 5 if --page-refresh is set)"},
{"--output-dir", "<string>", "Directory for generated prompt files (default: bauer-output)"},
{"--model", "<string>", "Copilot model to use for sessions (default: gpt-5-mini-high)"},
{"--summary-model", "<string>", "Copilot model to use for summary session (default: gpt-5-mini-high)"},
{"--target-repo", "<string>", "Path to target repository where tasks should be executed (default: current directory)"},
}

Expand Down Expand Up @@ -76,12 +72,10 @@ func Load() (*Config, error) {
cfg := &Config{
DocID: *docID,
CredentialsPath: *credentialsPath,
DryRun: *dryRun,
ParseOnly: *parseOnly,
ChunkSize: *chunkSize,
PageRefresh: *pageRefresh,
OutputDir: *outputDir,
Model: *model,
SummaryModel: *summaryModel,
TargetRepo: *targetRepo,
}

Expand Down
19 changes: 1 addition & 18 deletions internal/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,7 @@ type Config struct {
// CredentialsPath is the path to the Google Cloud service account JSON key file.
CredentialsPath string `json:"credentials"`

// DryRun indicates if the tool should skip side-effect operations (Copilot CLI, PR creation).
DryRun bool `json:"dry_run"`

// ParseOnly indicates Phase 1 mode - parse document only, skip Copilot execution and GitHub integration
// ParseOnly indicates Phase 1 mode - parse document only, skip GitHub integration
ParseOnly bool `json:"parse_only"`

// ChunkSize is the total number of chunks to create from all locations.
Expand All @@ -33,14 +30,6 @@ type Config struct {
// Default is "bauer-output" if not specified.
OutputDir string `json:"output_dir"`

// Model is the Copilot model to use for sessions.
// Default is "gpt-5-mini-high" if not specified.
Model string `json:"model"`

// SummaryModel is the Copilot model to use for the summary session.
// Default is "gpt-5-mini-high" if not specified.
SummaryModel string `json:"summary_model"`

// TargetRepo is the path (relative or absolute) to the target repository
// where tasks should be executed. If not specified, uses the current directory.
TargetRepo string `json:"target_repo"`
Expand All @@ -58,12 +47,6 @@ func (c *Config) ApplyDefaults() {
if c.OutputDir == "" {
c.OutputDir = "bauer-output"
}
if c.Model == "" {
c.Model = "gpt-5-mini-high"
}
if c.SummaryModel == "" {
c.SummaryModel = "gpt-5-mini-high"
}
}

// Validate checks if the configuration is valid.
Expand Down
18 changes: 0 additions & 18 deletions internal/config/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,6 @@ func TestConfig_Validate(t *testing.T) {
CredentialsPath: validCredsFile,
ChunkSize: 1,
OutputDir: "bauer-output",
Model: "gpt-4",
SummaryModel: "gpt-4",
},
wantErr: false,
},
Expand All @@ -37,8 +35,6 @@ func TestConfig_Validate(t *testing.T) {
DocID: "",
CredentialsPath: validCredsFile,
ChunkSize: 1,
Model: "gpt-4",
SummaryModel: "gpt-4",
},
wantErr: true,
},
Expand All @@ -48,8 +44,6 @@ func TestConfig_Validate(t *testing.T) {
DocID: "some-doc-id",
CredentialsPath: "",
ChunkSize: 1,
Model: "gpt-4",
SummaryModel: "gpt-4",
},
wantErr: true,
},
Expand All @@ -59,8 +53,6 @@ func TestConfig_Validate(t *testing.T) {
DocID: "some-doc-id",
CredentialsPath: filepath.Join(tmpDir, "non-existent.json"),
ChunkSize: 1,
Model: "gpt-4",
SummaryModel: "gpt-4",
},
wantErr: true,
},
Expand All @@ -70,8 +62,6 @@ func TestConfig_Validate(t *testing.T) {
DocID: "some-doc-id",
CredentialsPath: tmpDir,
ChunkSize: 1,
Model: "gpt-4",
SummaryModel: "gpt-4",
},
wantErr: true,
},
Expand All @@ -81,8 +71,6 @@ func TestConfig_Validate(t *testing.T) {
DocID: "some-doc-id",
CredentialsPath: validCredsFile,
ChunkSize: -1,
Model: "gpt-4",
SummaryModel: "gpt-4",
},
wantErr: true,
},
Expand All @@ -93,8 +81,6 @@ func TestConfig_Validate(t *testing.T) {
CredentialsPath: validCredsFile,
ChunkSize: 1,
OutputDir: "bauer-output",
Model: "gpt-5-mini-high",
SummaryModel: "gpt-5-mini-high",
},
wantErr: false,
},
Expand All @@ -105,8 +91,6 @@ func TestConfig_Validate(t *testing.T) {
CredentialsPath: validCredsFile,
ChunkSize: 1,
OutputDir: "bauer-output",
Model: "",
SummaryModel: "",
},
wantErr: false,
},
Expand Down Expand Up @@ -185,8 +169,6 @@ func TestChunkSizeDefaults(t *testing.T) {
ChunkSize: effectiveChunkSize,
PageRefresh: tt.pageRefreshFlag,
OutputDir: "bauer-output",
Model: "gpt-5-mini-high",
SummaryModel: "gpt-5-mini-high",
}

// Validate should pass
Expand Down
Loading
Loading