delimit-cli 1.0.0 → 2.1.0
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/.github/workflows/api-governance.yml +24 -0
- package/README.md +57 -115
- package/adapters/codex-skill.js +87 -0
- package/adapters/cursor-extension.js +190 -0
- package/adapters/gemini-action.js +93 -0
- package/adapters/openai-function.js +112 -0
- package/adapters/xai-plugin.js +151 -0
- package/bin/delimit-cli.js +921 -0
- package/bin/delimit.js +237 -1
- package/delimit.yml +19 -0
- package/hooks/evidence-status.sh +12 -0
- package/hooks/git/commit-msg +4 -0
- package/hooks/git/pre-commit +4 -0
- package/hooks/git/pre-push +4 -0
- package/hooks/install-hooks.sh +583 -0
- package/hooks/message-auth-hook.js +9 -0
- package/hooks/message-governance-hook.js +9 -0
- package/hooks/models/claude-post.js +4 -0
- package/hooks/models/claude-pre.js +4 -0
- package/hooks/models/codex-post.js +4 -0
- package/hooks/models/codex-pre.js +4 -0
- package/hooks/models/cursor-post.js +4 -0
- package/hooks/models/cursor-pre.js +4 -0
- package/hooks/models/gemini-post.js +4 -0
- package/hooks/models/gemini-pre.js +4 -0
- package/hooks/models/openai-post.js +4 -0
- package/hooks/models/openai-pre.js +4 -0
- package/hooks/models/windsurf-post.js +4 -0
- package/hooks/models/windsurf-pre.js +4 -0
- package/hooks/models/xai-post.js +4 -0
- package/hooks/models/xai-pre.js +4 -0
- package/hooks/post-bash-hook.js +13 -0
- package/hooks/post-mcp-hook.js +13 -0
- package/hooks/post-response-hook.js +4 -0
- package/hooks/post-tool-hook.js +126 -0
- package/hooks/post-write-hook.js +13 -0
- package/hooks/pre-bash-hook.js +30 -0
- package/hooks/pre-mcp-hook.js +13 -0
- package/hooks/pre-read-hook.js +13 -0
- package/hooks/pre-search-hook.js +13 -0
- package/hooks/pre-submit-hook.js +4 -0
- package/hooks/pre-task-hook.js +13 -0
- package/hooks/pre-tool-hook.js +121 -0
- package/hooks/pre-web-hook.js +13 -0
- package/hooks/pre-write-hook.js +31 -0
- package/hooks/test-hooks.sh +12 -0
- package/hooks/update-delimit.sh +6 -0
- package/lib/agent.js +509 -0
- package/lib/api-engine.js +156 -0
- package/lib/auth-setup.js +891 -0
- package/lib/decision-engine.js +474 -0
- package/lib/hooks-installer.js +416 -0
- package/lib/platform-adapters.js +353 -0
- package/lib/proxy-handler.js +114 -0
- package/package.json +38 -30
- package/scripts/infect.js +128 -0
- package/test-decision-engine.js +181 -0
- package/test-hook.js +27 -0
- package/dist/commands/validate.d.ts +0 -2
- package/dist/commands/validate.d.ts.map +0 -1
- package/dist/commands/validate.js +0 -106
- package/dist/commands/validate.js.map +0 -1
- package/dist/index.d.ts +0 -3
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js +0 -71
- package/dist/index.js.map +0 -1
- package/dist/types/index.d.ts +0 -39
- package/dist/types/index.d.ts.map +0 -1
- package/dist/types/index.js +0 -3
- package/dist/types/index.js.map +0 -1
- package/dist/utils/api.d.ts +0 -3
- package/dist/utils/api.d.ts.map +0 -1
- package/dist/utils/api.js +0 -64
- package/dist/utils/api.js.map +0 -1
- package/dist/utils/file.d.ts +0 -7
- package/dist/utils/file.d.ts.map +0 -1
- package/dist/utils/file.js +0 -69
- package/dist/utils/file.js.map +0 -1
- package/dist/utils/logger.d.ts +0 -14
- package/dist/utils/logger.d.ts.map +0 -1
- package/dist/utils/logger.js +0 -28
- package/dist/utils/logger.js.map +0 -1
- package/dist/utils/masker.d.ts +0 -14
- package/dist/utils/masker.d.ts.map +0 -1
- package/dist/utils/masker.js +0 -89
- package/dist/utils/masker.js.map +0 -1
- package/src/commands/validate.ts +0 -150
- package/src/index.ts +0 -80
- package/src/types/index.ts +0 -41
- package/src/utils/api.ts +0 -68
- package/src/utils/file.ts +0 -71
- package/src/utils/logger.ts +0 -27
- package/src/utils/masker.ts +0 -101
- package/test-sensitive.yaml +0 -109
- package/tsconfig.json +0 -23
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
name: API Governance
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
pull_request:
|
|
5
|
+
paths:
|
|
6
|
+
- '**.json'
|
|
7
|
+
- '**.yaml'
|
|
8
|
+
- '**.yml'
|
|
9
|
+
- 'openapi/**'
|
|
10
|
+
- 'api/**'
|
|
11
|
+
- 'swagger/**'
|
|
12
|
+
|
|
13
|
+
jobs:
|
|
14
|
+
api-check:
|
|
15
|
+
runs-on: ubuntu-latest
|
|
16
|
+
steps:
|
|
17
|
+
- uses: actions/checkout@v3
|
|
18
|
+
with:
|
|
19
|
+
fetch-depth: 0
|
|
20
|
+
|
|
21
|
+
- name: Detect API breaking changes
|
|
22
|
+
uses: delimit-ai/delimit-action@v1
|
|
23
|
+
with:
|
|
24
|
+
advisory_mode: true
|
package/README.md
CHANGED
|
@@ -1,157 +1,99 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Delimit
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
**API governance CLI for development teams.** Detect breaking API changes, enforce policies, and maintain audit trails across your services.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
[](https://www.npmjs.com/package/delimit)
|
|
6
|
+
[](https://opensource.org/licenses/MIT)
|
|
6
7
|
|
|
7
|
-
|
|
8
|
-
- ✅ **OpenAPI Validation**: Validate specs against governance rules
|
|
9
|
-
- 🎨 **Beautiful Output**: Color-coded terminal output for easy reading
|
|
10
|
-
- 🚀 **Fast & Lightweight**: Built with TypeScript for performance
|
|
11
|
-
- 🔒 **Secure by Design**: Your sensitive API data never leaves your machine
|
|
12
|
-
|
|
13
|
-
## Installation
|
|
14
|
-
|
|
15
|
-
```bash
|
|
16
|
-
npm install -g delimit-cli
|
|
17
|
-
```
|
|
18
|
-
|
|
19
|
-
Or with yarn:
|
|
8
|
+
## Install
|
|
20
9
|
|
|
21
10
|
```bash
|
|
22
|
-
|
|
11
|
+
npm install -g delimit
|
|
23
12
|
```
|
|
24
13
|
|
|
25
14
|
## Quick Start
|
|
26
15
|
|
|
27
|
-
1. Get your API key from [RapidAPI](https://rapidapi.com/delimit/api/openapi-diff-api)
|
|
28
|
-
|
|
29
|
-
2. Set your API key as an environment variable:
|
|
30
16
|
```bash
|
|
31
|
-
|
|
32
|
-
|
|
17
|
+
# Check current governance status
|
|
18
|
+
delimit status
|
|
33
19
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
delimit validate api-spec.yaml
|
|
37
|
-
```
|
|
20
|
+
# Set up governance for this repo (advisory mode by default)
|
|
21
|
+
delimit install --mode advisory
|
|
38
22
|
|
|
39
|
-
|
|
23
|
+
# Validate an API spec
|
|
24
|
+
delimit validate api/openapi.yaml
|
|
25
|
+
```
|
|
40
26
|
|
|
41
|
-
|
|
27
|
+
## Governance Modes
|
|
42
28
|
|
|
43
|
-
|
|
29
|
+
Delimit supports three enforcement levels. You choose:
|
|
44
30
|
|
|
45
31
|
```bash
|
|
46
|
-
delimit
|
|
32
|
+
delimit install --mode advisory # Warnings only, no blocking
|
|
33
|
+
delimit install --mode guarded # Soft enforcement with overrides
|
|
34
|
+
delimit install --mode enforce # Strict policy enforcement
|
|
47
35
|
```
|
|
48
36
|
|
|
49
|
-
|
|
50
|
-
- `--verbose` - Show detailed validation output
|
|
51
|
-
- `--output <format>` - Output format: `text` (default) or `json`
|
|
37
|
+
### Scope Control
|
|
52
38
|
|
|
53
|
-
**Example:**
|
|
54
39
|
```bash
|
|
55
|
-
#
|
|
56
|
-
delimit
|
|
57
|
-
|
|
58
|
-
# Validate a JSON spec with verbose output
|
|
59
|
-
delimit validate api.json --verbose
|
|
60
|
-
|
|
61
|
-
# Get JSON output for CI/CD integration
|
|
62
|
-
delimit validate spec.yaml --output json
|
|
40
|
+
delimit install --scope repo # Current repository only
|
|
41
|
+
delimit install --scope global # All repositories on this machine
|
|
63
42
|
```
|
|
64
43
|
|
|
65
|
-
|
|
44
|
+
## What It Does
|
|
66
45
|
|
|
67
|
-
-
|
|
68
|
-
-
|
|
69
|
-
-
|
|
70
|
-
-
|
|
46
|
+
- **API Change Detection** — Identifies breaking changes in OpenAPI/Swagger specs
|
|
47
|
+
- **Policy Enforcement** — Applies configurable governance rules to API changes
|
|
48
|
+
- **Evidence Collection** — Records audit trail of all governance decisions
|
|
49
|
+
- **MCP Integration** — Works with Claude, Gemini, and other AI coding tools via Model Context Protocol
|
|
71
50
|
|
|
72
|
-
##
|
|
51
|
+
## Usage with CI
|
|
73
52
|
|
|
74
|
-
|
|
53
|
+
For CI/CD integration, use the GitHub Action instead:
|
|
75
54
|
|
|
76
|
-
|
|
77
|
-
-
|
|
78
|
-
|
|
79
|
-
- Server URLs
|
|
80
|
-
- Contact information
|
|
81
|
-
- License and terms of service
|
|
55
|
+
```yaml
|
|
56
|
+
- uses: delimit-ai/delimit-action@v1
|
|
57
|
+
```
|
|
82
58
|
|
|
83
|
-
|
|
84
|
-
- API structure and schemas
|
|
85
|
-
- Endpoints and methods
|
|
86
|
-
- Parameters and types
|
|
87
|
-
- Required fields and validations
|
|
59
|
+
See [delimit-action](https://github.com/delimit-ai/delimit-action) for full CI setup.
|
|
88
60
|
|
|
89
|
-
|
|
61
|
+
## Commands
|
|
90
62
|
|
|
91
|
-
|
|
63
|
+
| Command | Description |
|
|
64
|
+
|---------|-------------|
|
|
65
|
+
| `delimit status` | Show current governance state |
|
|
66
|
+
| `delimit install` | Set up governance hooks and config |
|
|
67
|
+
| `delimit validate <spec>` | Validate an API specification |
|
|
68
|
+
| `delimit doctor` | Diagnose configuration issues |
|
|
69
|
+
| `delimit uninstall` | Clean removal of all hooks and config |
|
|
92
70
|
|
|
93
|
-
|
|
71
|
+
## Uninstall
|
|
94
72
|
|
|
95
|
-
```
|
|
96
|
-
|
|
97
|
-
run: |
|
|
98
|
-
npm install -g delimit-cli
|
|
99
|
-
export DELIMIT_API_KEY=${{ secrets.DELIMIT_API_KEY }}
|
|
100
|
-
delimit validate openapi.yaml
|
|
73
|
+
```bash
|
|
74
|
+
delimit uninstall
|
|
101
75
|
```
|
|
102
76
|
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
```groovy
|
|
106
|
-
stage('API Validation') {
|
|
107
|
-
steps {
|
|
108
|
-
sh '''
|
|
109
|
-
npm install -g delimit-cli
|
|
110
|
-
export DELIMIT_API_KEY=${DELIMIT_API_KEY}
|
|
111
|
-
delimit validate openapi.yaml
|
|
112
|
-
'''
|
|
113
|
-
}
|
|
114
|
-
}
|
|
115
|
-
```
|
|
77
|
+
Cleanly removes all hooks, PATH modifications, and configuration files.
|
|
116
78
|
|
|
117
|
-
|
|
79
|
+
## Configuration
|
|
80
|
+
|
|
81
|
+
Create `.delimit/policies.yml` in your repository:
|
|
118
82
|
|
|
119
83
|
```yaml
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
84
|
+
rules:
|
|
85
|
+
- id: no_endpoint_removal
|
|
86
|
+
change_types: [endpoint_removed]
|
|
87
|
+
severity: error
|
|
88
|
+
message: "Endpoints cannot be removed without deprecation"
|
|
125
89
|
```
|
|
126
90
|
|
|
127
|
-
##
|
|
128
|
-
|
|
129
|
-
- `0` - Validation passed
|
|
130
|
-
- `1` - Validation failed or error occurred
|
|
131
|
-
|
|
132
|
-
## Environment Variables
|
|
133
|
-
|
|
134
|
-
- `DELIMIT_API_KEY` - Your RapidAPI key (required)
|
|
135
|
-
- `DELIMIT_API_URL` - Override API URL (optional, for testing)
|
|
91
|
+
## Links
|
|
136
92
|
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
-
|
|
140
|
-
- **Issues**: https://github.com/delimit-ai/delimit-cli/issues
|
|
141
|
-
- **Email**: support@delimit.ai
|
|
93
|
+
- [GitHub Action](https://github.com/delimit-ai/delimit-action) — CI/CD integration
|
|
94
|
+
- [Website](https://delimit.ai) — Documentation and platform
|
|
95
|
+
- [Issues](https://github.com/delimit-ai/delimit/issues) — Bug reports and feature requests
|
|
142
96
|
|
|
143
97
|
## License
|
|
144
98
|
|
|
145
|
-
MIT
|
|
146
|
-
|
|
147
|
-
## Contributing
|
|
148
|
-
|
|
149
|
-
We welcome contributions! Please see our [Contributing Guide](CONTRIBUTING.md) for details.
|
|
150
|
-
|
|
151
|
-
## Security
|
|
152
|
-
|
|
153
|
-
Found a security issue? Please email security@delimit.ai directly.
|
|
154
|
-
|
|
155
|
-
---
|
|
156
|
-
|
|
157
|
-
Built with ❤️ by the Delimit team
|
|
99
|
+
MIT
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Delimit™ Codex Skill Adapter
|
|
4
|
+
* Implements GitHub Codex "Skills" interface
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
const axios = require('axios');
|
|
8
|
+
const AGENT_URL = `http://127.0.0.1:${process.env.DELIMIT_AGENT_PORT || 7823}`;
|
|
9
|
+
|
|
10
|
+
class DelimitCodexSkill {
|
|
11
|
+
constructor() {
|
|
12
|
+
this.name = 'delimit-governance';
|
|
13
|
+
this.version = '2.0.0';
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Codex Skills use onBeforeSuggestion and onAfterAccept events
|
|
18
|
+
*/
|
|
19
|
+
async onBeforeSuggestion(context) {
|
|
20
|
+
console.log('[DELIMIT CODEX] Validating code suggestion...');
|
|
21
|
+
|
|
22
|
+
try {
|
|
23
|
+
const { code, language, file } = context;
|
|
24
|
+
|
|
25
|
+
// Check governance rules
|
|
26
|
+
const response = await axios.post(`${AGENT_URL}/evaluate`, {
|
|
27
|
+
action: 'codex_suggestion',
|
|
28
|
+
code: code,
|
|
29
|
+
language: language,
|
|
30
|
+
file: file,
|
|
31
|
+
tool: 'codex'
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
if (response.data.action === 'block') {
|
|
35
|
+
return {
|
|
36
|
+
allow: false,
|
|
37
|
+
message: `[DELIMIT] Code blocked: ${response.data.reason}`
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
if (response.data.action === 'prompt') {
|
|
42
|
+
return {
|
|
43
|
+
allow: true,
|
|
44
|
+
warning: response.data.message
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
return { allow: true };
|
|
49
|
+
} catch (error) {
|
|
50
|
+
console.warn('[DELIMIT CODEX] Governance check failed:', error.message);
|
|
51
|
+
return { allow: true }; // Fail open
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
async onAfterAccept(context) {
|
|
56
|
+
console.log('[DELIMIT CODEX] Recording accepted suggestion...');
|
|
57
|
+
|
|
58
|
+
try {
|
|
59
|
+
// Collect evidence
|
|
60
|
+
await axios.post(`${AGENT_URL}/audit`, {
|
|
61
|
+
action: 'codex_accept',
|
|
62
|
+
context: context,
|
|
63
|
+
timestamp: new Date().toISOString()
|
|
64
|
+
});
|
|
65
|
+
} catch (error) {
|
|
66
|
+
// Silent fail for audit
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
// Codex-specific command handler
|
|
71
|
+
async handleCommand(command, args) {
|
|
72
|
+
if (command === 'governance') {
|
|
73
|
+
const { execSync } = require('child_process');
|
|
74
|
+
return execSync('delimit status --verbose').toString();
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
// Export for Codex
|
|
80
|
+
if (typeof module !== 'undefined' && module.exports) {
|
|
81
|
+
module.exports = new DelimitCodexSkill();
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
// Codex registration
|
|
85
|
+
if (typeof registerSkill === 'function') {
|
|
86
|
+
registerSkill(new DelimitCodexSkill());
|
|
87
|
+
}
|
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Delimit™ Cursor Extension Adapter
|
|
4
|
+
* Implements VSCode-style extension for Cursor
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
const vscode = typeof acquireVsCodeApi !== 'undefined' ? acquireVsCodeApi() : null;
|
|
8
|
+
const axios = require('axios');
|
|
9
|
+
const AGENT_URL = `http://127.0.0.1:${process.env.DELIMIT_AGENT_PORT || 7823}`;
|
|
10
|
+
|
|
11
|
+
class DelimitCursorExtension {
|
|
12
|
+
constructor() {
|
|
13
|
+
this.extensionId = 'delimit.governance';
|
|
14
|
+
this.version = '2.0.0';
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Extension activation
|
|
19
|
+
*/
|
|
20
|
+
async activate(context) {
|
|
21
|
+
console.log('[DELIMIT CURSOR] Extension activated');
|
|
22
|
+
|
|
23
|
+
// Register commands
|
|
24
|
+
this.registerCommands(context);
|
|
25
|
+
|
|
26
|
+
// Register code action provider
|
|
27
|
+
this.registerCodeActions(context);
|
|
28
|
+
|
|
29
|
+
// Register diagnostics
|
|
30
|
+
this.registerDiagnostics(context);
|
|
31
|
+
|
|
32
|
+
return {
|
|
33
|
+
extendMarkdownIt: (md) => this.extendMarkdown(md)
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
registerCommands(context) {
|
|
38
|
+
const commands = {
|
|
39
|
+
'delimit.checkGovernance': async () => {
|
|
40
|
+
const { execSync } = require('child_process');
|
|
41
|
+
const result = execSync('delimit status --verbose').toString();
|
|
42
|
+
this.showMessage(result);
|
|
43
|
+
},
|
|
44
|
+
'delimit.switchMode': async () => {
|
|
45
|
+
const mode = await this.showQuickPick(['advisory', 'guarded', 'enforce']);
|
|
46
|
+
if (mode) {
|
|
47
|
+
const { execSync } = require('child_process');
|
|
48
|
+
execSync(`delimit mode ${mode}`);
|
|
49
|
+
this.showMessage(`Switched to ${mode} mode`);
|
|
50
|
+
}
|
|
51
|
+
},
|
|
52
|
+
'delimit.viewAudit': async () => {
|
|
53
|
+
const { execSync } = require('child_process');
|
|
54
|
+
const audit = execSync('delimit audit --tail 20').toString();
|
|
55
|
+
this.showMessage(audit, 'Audit Log');
|
|
56
|
+
}
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
Object.entries(commands).forEach(([cmd, handler]) => {
|
|
60
|
+
if (vscode) {
|
|
61
|
+
context.subscriptions.push(
|
|
62
|
+
vscode.commands.registerCommand(cmd, handler)
|
|
63
|
+
);
|
|
64
|
+
}
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
registerCodeActions(context) {
|
|
69
|
+
// Register code action provider for all languages
|
|
70
|
+
const provider = {
|
|
71
|
+
provideCodeActions: async (document, range, context) => {
|
|
72
|
+
const actions = [];
|
|
73
|
+
|
|
74
|
+
// Check if there are any governance issues
|
|
75
|
+
const text = document.getText(range);
|
|
76
|
+
const issues = await this.checkGovernance(text, document.languageId);
|
|
77
|
+
|
|
78
|
+
if (issues.length > 0) {
|
|
79
|
+
actions.push({
|
|
80
|
+
title: '🛡️ Fix Governance Issues',
|
|
81
|
+
command: 'delimit.fixIssues',
|
|
82
|
+
arguments: [issues]
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
return actions;
|
|
87
|
+
}
|
|
88
|
+
};
|
|
89
|
+
|
|
90
|
+
if (vscode) {
|
|
91
|
+
context.subscriptions.push(
|
|
92
|
+
vscode.languages.registerCodeActionsProvider('*', provider)
|
|
93
|
+
);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
registerDiagnostics(context) {
|
|
98
|
+
const diagnosticCollection = vscode ?
|
|
99
|
+
vscode.languages.createDiagnosticCollection('delimit') : null;
|
|
100
|
+
|
|
101
|
+
// Watch for document changes
|
|
102
|
+
if (vscode) {
|
|
103
|
+
vscode.workspace.onDidChangeTextDocument(async (event) => {
|
|
104
|
+
const document = event.document;
|
|
105
|
+
const diagnostics = [];
|
|
106
|
+
|
|
107
|
+
// Check governance
|
|
108
|
+
const text = document.getText();
|
|
109
|
+
const issues = await this.checkGovernance(text, document.languageId);
|
|
110
|
+
|
|
111
|
+
issues.forEach(issue => {
|
|
112
|
+
diagnostics.push({
|
|
113
|
+
range: new vscode.Range(
|
|
114
|
+
issue.line || 0,
|
|
115
|
+
issue.column || 0,
|
|
116
|
+
issue.line || 0,
|
|
117
|
+
issue.columnEnd || 100
|
|
118
|
+
),
|
|
119
|
+
message: issue.message,
|
|
120
|
+
severity: issue.severity === 'error' ?
|
|
121
|
+
vscode.DiagnosticSeverity.Error :
|
|
122
|
+
vscode.DiagnosticSeverity.Warning
|
|
123
|
+
});
|
|
124
|
+
});
|
|
125
|
+
|
|
126
|
+
diagnosticCollection.set(document.uri, diagnostics);
|
|
127
|
+
});
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
context.subscriptions.push(diagnosticCollection);
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
async checkGovernance(code, language) {
|
|
134
|
+
try {
|
|
135
|
+
const response = await axios.post(`${AGENT_URL}/evaluate`, {
|
|
136
|
+
action: 'cursor_validation',
|
|
137
|
+
code: code,
|
|
138
|
+
language: language,
|
|
139
|
+
tool: 'cursor'
|
|
140
|
+
});
|
|
141
|
+
|
|
142
|
+
if (response.data.issues) {
|
|
143
|
+
return response.data.issues;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
return [];
|
|
147
|
+
} catch (error) {
|
|
148
|
+
return [];
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
showMessage(message, title = 'Delimit') {
|
|
153
|
+
if (vscode) {
|
|
154
|
+
vscode.window.showInformationMessage(`${title}: ${message}`);
|
|
155
|
+
} else {
|
|
156
|
+
console.log(`[${title}] ${message}`);
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
async showQuickPick(items) {
|
|
161
|
+
if (vscode) {
|
|
162
|
+
return await vscode.window.showQuickPick(items);
|
|
163
|
+
}
|
|
164
|
+
return items[0];
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
extendMarkdown(md) {
|
|
168
|
+
// Add custom markdown rendering for governance info
|
|
169
|
+
return md.use((md) => {
|
|
170
|
+
md.renderer.rules.delimit_governance = (tokens, idx) => {
|
|
171
|
+
return `<div class="delimit-governance">${tokens[idx].content}</div>`;
|
|
172
|
+
};
|
|
173
|
+
});
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
deactivate() {
|
|
177
|
+
console.log('[DELIMIT CURSOR] Extension deactivated');
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
// Export for Cursor/VSCode
|
|
182
|
+
if (typeof module !== 'undefined' && module.exports) {
|
|
183
|
+
module.exports = new DelimitCursorExtension();
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
// VSCode activation
|
|
187
|
+
if (vscode) {
|
|
188
|
+
exports.activate = (context) => new DelimitCursorExtension().activate(context);
|
|
189
|
+
exports.deactivate = () => new DelimitCursorExtension().deactivate();
|
|
190
|
+
}
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Delimit™ Gemini Action Adapter
|
|
4
|
+
* Implements Google Gemini Extensions interface
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
const axios = require('axios');
|
|
8
|
+
const AGENT_URL = `http://127.0.0.1:${process.env.DELIMIT_AGENT_PORT || 7823}`;
|
|
9
|
+
|
|
10
|
+
class DelimitGeminiAction {
|
|
11
|
+
constructor() {
|
|
12
|
+
this.id = 'delimit-governance';
|
|
13
|
+
this.version = '2.0.0';
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Gemini uses action handlers for extension points
|
|
18
|
+
*/
|
|
19
|
+
async beforeCodeGeneration(request) {
|
|
20
|
+
console.log('[DELIMIT GEMINI] Pre-generation validation...');
|
|
21
|
+
|
|
22
|
+
try {
|
|
23
|
+
const { prompt, context, model } = request;
|
|
24
|
+
|
|
25
|
+
// Check if the request involves sensitive operations
|
|
26
|
+
const response = await axios.post(`${AGENT_URL}/evaluate`, {
|
|
27
|
+
action: 'gemini_generation',
|
|
28
|
+
prompt: prompt,
|
|
29
|
+
context: context,
|
|
30
|
+
model: model || 'gemini-pro',
|
|
31
|
+
tool: 'gemini'
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
if (response.data.action === 'block') {
|
|
35
|
+
throw new Error(`[DELIMIT] Generation blocked: ${response.data.reason}`);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
if (response.data.action === 'prompt') {
|
|
39
|
+
console.warn(`[DELIMIT] Warning: ${response.data.message}`);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
return request; // Pass through
|
|
43
|
+
} catch (error) {
|
|
44
|
+
if (error.message.includes('[DELIMIT]')) {
|
|
45
|
+
throw error; // Re-throw governance blocks
|
|
46
|
+
}
|
|
47
|
+
console.warn('[DELIMIT GEMINI] Governance check failed:', error.message);
|
|
48
|
+
return request; // Fail open
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
async afterResponse(response) {
|
|
53
|
+
console.log('[DELIMIT GEMINI] Processing response...');
|
|
54
|
+
|
|
55
|
+
try {
|
|
56
|
+
// Collect evidence
|
|
57
|
+
await axios.post(`${AGENT_URL}/audit`, {
|
|
58
|
+
action: 'gemini_response',
|
|
59
|
+
response: {
|
|
60
|
+
model: response.model,
|
|
61
|
+
tokens: response.usage,
|
|
62
|
+
timestamp: new Date().toISOString()
|
|
63
|
+
}
|
|
64
|
+
});
|
|
65
|
+
} catch (error) {
|
|
66
|
+
// Silent fail for audit
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
return response;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
// Gemini command handler (uses @ prefix)
|
|
73
|
+
async handleCommand(command, args) {
|
|
74
|
+
const commands = {
|
|
75
|
+
'@governance': 'delimit status',
|
|
76
|
+
'@audit': 'delimit audit',
|
|
77
|
+
'@mode': 'delimit mode'
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
if (commands[command]) {
|
|
81
|
+
const { execSync } = require('child_process');
|
|
82
|
+
return execSync(commands[command]).toString();
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
// Export for Gemini
|
|
88
|
+
module.exports = new DelimitGeminiAction();
|
|
89
|
+
|
|
90
|
+
// Gemini registration (if available)
|
|
91
|
+
if (typeof registerExtension === 'function') {
|
|
92
|
+
registerExtension(new DelimitGeminiAction());
|
|
93
|
+
}
|