@aakrit512/gatekeep 1.0.0 → 1.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,46 +1,70 @@
1
1
  # Gatekeep
2
2
 
3
- A local, browser-based coding agent for reviewing and exploring projects with an OpenAI-compatible chat model. It runs on your machine, keeps project metadata and chat history in a local SQLite database, and gives the model a small set of read/review tools for inspecting a repository.
3
+ Gatekeep is a local web app for reviewing codebases with an OpenAI-compatible model.
4
+ It runs on your machine, keeps project/chat history locally, and helps you initialize and inspect repositories safely.
4
5
 
5
- ## What It Does
6
+ ## What You Get
6
7
 
7
- - Starts a local web UI for saved projects and project chat.
8
- - Initializes a project by creating `docs/intro.md` inside the target repository.
9
- - Stores project metadata, chat messages, tool traces, token usage, and estimated costs locally.
10
- - Lets you run provider/config/project doctor checks from the browser.
11
- - Supports OpenAI-compatible providers through `AI_API_KEY`, `AI_BASE_URL`, and `MODEL_NAME`.
8
+ - Local browser UI for project setup and chat-based review.
9
+ - One-click project initialization that creates `docs/intro.md` in the selected repo.
10
+ - Built-in Doctor checks for Node runtime, API config, and project path readiness.
11
+ - Local storage for project history, tool traces, token usage, and estimated cost.
12
12
 
13
- ## Quick Start
13
+ ## Requirements
14
+
15
+ - Node.js `20+`
16
+ - An OpenAI-compatible API key
17
+
18
+ ## Install
19
+
20
+ Install from npm (recommended):
21
+
22
+ ```sh
23
+ npm install --global @aakrit512/gatekeep
24
+ ```
25
+
26
+ Or run from source:
14
27
 
15
28
  ```sh
16
29
  pnpm install
17
30
  pnpm run build
18
31
  pnpm link --global
19
- gatekeep start --project /path/to/repo
20
32
  ```
21
33
 
22
- The UI starts at:
34
+ ## Start Gatekeep
23
35
 
24
- ```txt
25
- http://127.0.0.1:9808
36
+ ```sh
37
+ gatekeep start --project /path/to/repo
26
38
  ```
27
39
 
28
- You can also launch it for the current directory:
40
+ Defaults:
41
+
42
+ - Host: `127.0.0.1`
43
+ - Port: `9808`
44
+
45
+ You can also run:
29
46
 
30
47
  ```sh
31
48
  gatekeep start --project .
49
+ gatekeep start --port 9809 --host 0.0.0.0
32
50
  ```
33
51
 
34
- After publishing to npm, install and run it globally:
52
+ Then open `http://127.0.0.1:9808`.
35
53
 
36
- ```sh
37
- npm install --global @aakrit512/gatekeep
38
- gatekeep start
39
- ```
54
+ ## First-Run Setup (In the UI)
40
55
 
41
- ## Configuration
56
+ 1. Choose a project directory.
57
+ 2. Open **Config** and set:
58
+ - `AI_API_KEY`
59
+ - `AI_BASE_URL` (for example `https://api.openai.com/v1`)
60
+ - `MODEL_NAME` (for example `gpt-4o`)
61
+ 3. Run **Doctor** and fix any reported issues.
62
+ 4. Click **Initialize** to generate `docs/intro.md`.
63
+ 5. Start chatting in the review panel.
42
64
 
43
- Create a local `.env` file or configure values in the browser UI:
65
+ ## Environment Variables
66
+
67
+ You can set config through `.env` (or UI settings):
44
68
 
45
69
  ```sh
46
70
  AI_API_KEY=your_api_key
@@ -48,44 +72,20 @@ AI_BASE_URL=https://api.openai.com/v1
48
72
  MODEL_NAME=gpt-4o
49
73
  ```
50
74
 
51
- Project metadata and chat history are stored in your OS app-support/config directory, not in the project being reviewed. API keys are masked in UI responses and are not stored in the project database.
52
-
53
- ## Folder Structure
54
-
55
- ```txt
56
- .
57
- ├── src/
58
- │ ├── ai/ OpenAI client setup, chat completion calls, context trimming, summarization helpers.
59
- │ ├── cli/ User config storage and validation/doctor checks.
60
- │ ├── functions/ Tool definitions and local tool execution used by the agent.
61
- │ ├── prompts/ System and initialization prompts that guide repository review behavior.
62
- │ ├── ui/ Local HTTP server, project database layer, and browser-agent workflow.
63
- │ ├── cli.ts CLI entry point that starts the web UI.
64
- │ └── config.ts Shared runtime configuration defaults and helpers.
65
- ├── ui/
66
- │ └── app.html Browser UI document, styles, and client-side JavaScript.
67
- ├── package.json Package metadata, scripts, dependencies, and publish file list.
68
- ├── tsconfig.json TypeScript settings for development type checks.
69
- ├── tsconfig.build.json
70
- │ TypeScript build settings for emitted `dist/` output.
71
- ├── pnpm-lock.yaml Locked dependency graph.
72
- └── pnpm-workspace.yaml
73
- pnpm workspace declaration.
74
- ```
75
+ ## Local Data and Privacy
75
76
 
76
- `dist/`, `node_modules/`, local `.env` files, and SQLite runtime files are generated locally and intentionally ignored by git.
77
+ Gatekeep stores data under your OS config/app-support directory:
77
78
 
78
- ## Scripts
79
+ - `config.json` for provider/model/base URL/API key
80
+ - `projects.sqlite` for projects, chat history, activity traces, and usage
79
81
 
80
- ```sh
81
- pnpm run start # Run the TypeScript CLI directly with tsx.
82
- pnpm run build # Compile TypeScript into dist/.
83
- pnpm pack # Build and create the installable npm tarball.
84
- pnpm run typecheck # Type-check without emitting files.
85
- ```
86
-
87
- ## Development Notes
82
+ Nothing is uploaded except model API requests sent to your configured provider.
88
83
 
89
- The browser UI is intentionally plain HTML so the package stays small and the server can serve it without a frontend build step. The server injects the curated fallback model list into `ui/app.html` at request time.
84
+ ## Common Commands
90
85
 
91
- The agent tools are scoped to repository inspection and project initialization. During normal review/chat workflows, the model is guided to inspect files and diffs before answering.
86
+ ```sh
87
+ gatekeep --help
88
+ gatekeep start
89
+ gatekeep start --project .
90
+ pnpm run typecheck
91
+ ```
@@ -1,4 +1,4 @@
1
- import { execFileSync, execSync } from 'child_process';
1
+ import { execFileSync } from 'child_process';
2
2
  import { createHash } from 'crypto';
3
3
  import * as fs from 'fs';
4
4
  import * as path from 'path';
@@ -1016,18 +1016,22 @@ export function executeTool(name, args) {
1016
1016
  return `Success: Wrote ${content.length} characters to ${filePath}`;
1017
1017
  }
1018
1018
  if (name === 'get_git_diff') {
1019
- // Helper: run a git command and return stdout, or '' on failure (e.g. no commits yet)
1020
- const tryGit = (cmd) => {
1019
+ // Helper: run git subcommands without shell evaluation and return stdout.
1020
+ const tryGit = (args) => {
1021
1021
  try {
1022
- return execSync(cmd, { stdio: ['pipe', 'pipe', 'pipe'] }).toString().trim();
1022
+ return execFileSync('git', args, {
1023
+ cwd: process.cwd(),
1024
+ encoding: 'utf-8',
1025
+ stdio: ['pipe', 'pipe', 'pipe'],
1026
+ }).trim();
1023
1027
  }
1024
1028
  catch {
1025
1029
  return '';
1026
1030
  }
1027
1031
  };
1028
- const working = tryGit('git diff');
1029
- const staged = tryGit('git diff --cached');
1030
- const log = tryGit('git log --oneline --stat -10');
1032
+ const working = tryGit(['diff']);
1033
+ const staged = tryGit(['diff', '--cached']);
1034
+ const log = tryGit(['log', '--oneline', '--stat', '-10']);
1031
1035
  const sections = [
1032
1036
  `## Uncommitted changes (working tree)\n${working || 'None.'}`,
1033
1037
  `## Staged changes (index)\n${staged || 'None.'}`,
package/dist/ui/server.js CHANGED
@@ -112,34 +112,12 @@ function buildConfigFromBody(body) {
112
112
  function uniqueStrings(values) {
113
113
  return [...new Set(values.map((value) => value.trim()).filter(Boolean))];
114
114
  }
115
- function modelListUrl(baseUrl) {
116
- const normalized = baseUrl.endsWith('/') ? baseUrl : `${baseUrl}/`;
117
- return new URL('models', normalized).toString();
118
- }
119
115
  async function listModels(config) {
120
116
  const fallback = uniqueStrings([config.model, ...CURATED_OPENAI_MODELS]);
121
117
  if (!config.apiKey.trim()) {
122
- return { models: fallback, source: 'fallback', warning: 'Add an API key to load account models.' };
123
- }
124
- const response = await fetch(modelListUrl(config.baseUrl), {
125
- headers: {
126
- authorization: `Bearer ${config.apiKey}`,
127
- },
128
- });
129
- if (!response.ok) {
130
- return {
131
- models: fallback,
132
- source: 'fallback',
133
- warning: `Could not load models (${response.status}).`,
134
- };
118
+ return { models: fallback, source: 'static', warning: 'Add an API key to chat with the model you choose.' };
135
119
  }
136
- const body = await response.json();
137
- const available = new Set((body.data || []).map((model) => typeof model.id === 'string' ? model.id : '').filter(Boolean));
138
- const models = uniqueStrings([
139
- config.model,
140
- ...CURATED_OPENAI_MODELS.filter((model) => available.has(model)),
141
- ]);
142
- return { models: models.length ? models : fallback, source: 'api' };
120
+ return { models: fallback, source: 'static' };
143
121
  }
144
122
  function pickDirectory() {
145
123
  return new Promise((resolve, reject) => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aakrit512/gatekeep",
3
- "version": "1.0.0",
3
+ "version": "1.0.2",
4
4
  "description": "A local browser-based coding agent for project review and chat.",
5
5
  "main": "./dist/cli.js",
6
6
  "bin": {