delimit-cli 2.4.0 → 3.0.1

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.
Files changed (112) hide show
  1. package/.dockerignore +7 -0
  2. package/.github/workflows/ci.yml +22 -0
  3. package/CODE_OF_CONDUCT.md +48 -0
  4. package/CONTRIBUTING.md +67 -0
  5. package/Dockerfile +9 -0
  6. package/LICENSE +21 -0
  7. package/README.md +18 -69
  8. package/SECURITY.md +42 -0
  9. package/adapters/gemini-forge.js +11 -0
  10. package/adapters/gemini-jamsons.js +152 -0
  11. package/bin/delimit-cli.js +8 -0
  12. package/bin/delimit-setup.js +258 -0
  13. package/gateway/ai/backends/__init__.py +0 -0
  14. package/gateway/ai/backends/async_utils.py +21 -0
  15. package/gateway/ai/backends/deploy_bridge.py +150 -0
  16. package/gateway/ai/backends/gateway_core.py +261 -0
  17. package/gateway/ai/backends/generate_bridge.py +38 -0
  18. package/gateway/ai/backends/governance_bridge.py +196 -0
  19. package/gateway/ai/backends/intel_bridge.py +59 -0
  20. package/gateway/ai/backends/memory_bridge.py +93 -0
  21. package/gateway/ai/backends/ops_bridge.py +137 -0
  22. package/gateway/ai/backends/os_bridge.py +82 -0
  23. package/gateway/ai/backends/repo_bridge.py +117 -0
  24. package/gateway/ai/backends/ui_bridge.py +118 -0
  25. package/gateway/ai/backends/vault_bridge.py +129 -0
  26. package/gateway/ai/server.py +1182 -0
  27. package/gateway/core/__init__.py +3 -0
  28. package/gateway/core/__pycache__/__init__.cpython-310.pyc +0 -0
  29. package/gateway/core/__pycache__/auto_baseline.cpython-310.pyc +0 -0
  30. package/gateway/core/__pycache__/ci_formatter.cpython-310.pyc +0 -0
  31. package/gateway/core/__pycache__/contract_ledger.cpython-310.pyc +0 -0
  32. package/gateway/core/__pycache__/dependency_graph.cpython-310.pyc +0 -0
  33. package/gateway/core/__pycache__/dependency_manifest.cpython-310.pyc +0 -0
  34. package/gateway/core/__pycache__/diff_engine_v2.cpython-310.pyc +0 -0
  35. package/gateway/core/__pycache__/event_backbone.cpython-310.pyc +0 -0
  36. package/gateway/core/__pycache__/event_schema.cpython-310.pyc +0 -0
  37. package/gateway/core/__pycache__/explainer.cpython-310.pyc +0 -0
  38. package/gateway/core/__pycache__/gateway.cpython-310.pyc +0 -0
  39. package/gateway/core/__pycache__/gateway_v2.cpython-310.pyc +0 -0
  40. package/gateway/core/__pycache__/gateway_v3.cpython-310.pyc +0 -0
  41. package/gateway/core/__pycache__/impact_analyzer.cpython-310.pyc +0 -0
  42. package/gateway/core/__pycache__/policy_engine.cpython-310.pyc +0 -0
  43. package/gateway/core/__pycache__/registry.cpython-310.pyc +0 -0
  44. package/gateway/core/__pycache__/registry_v2.cpython-310.pyc +0 -0
  45. package/gateway/core/__pycache__/registry_v3.cpython-310.pyc +0 -0
  46. package/gateway/core/__pycache__/semver_classifier.cpython-310.pyc +0 -0
  47. package/gateway/core/__pycache__/spec_detector.cpython-310.pyc +0 -0
  48. package/gateway/core/__pycache__/surface_bridge.cpython-310.pyc +0 -0
  49. package/gateway/core/auto_baseline.py +304 -0
  50. package/gateway/core/ci_formatter.py +283 -0
  51. package/gateway/core/complexity_analyzer.py +386 -0
  52. package/gateway/core/contract_ledger.py +345 -0
  53. package/gateway/core/dependency_graph.py +218 -0
  54. package/gateway/core/dependency_manifest.py +223 -0
  55. package/gateway/core/diff_engine_v2.py +477 -0
  56. package/gateway/core/diff_engine_v2.py.bak +426 -0
  57. package/gateway/core/event_backbone.py +268 -0
  58. package/gateway/core/event_schema.py +258 -0
  59. package/gateway/core/explainer.py +438 -0
  60. package/gateway/core/gateway.py +128 -0
  61. package/gateway/core/gateway_v2.py +154 -0
  62. package/gateway/core/gateway_v3.py +224 -0
  63. package/gateway/core/impact_analyzer.py +163 -0
  64. package/gateway/core/policies/default.yml +13 -0
  65. package/gateway/core/policies/relaxed.yml +48 -0
  66. package/gateway/core/policies/strict.yml +55 -0
  67. package/gateway/core/policy_engine.py +464 -0
  68. package/gateway/core/registry.py +52 -0
  69. package/gateway/core/registry_v2.py +132 -0
  70. package/gateway/core/registry_v3.py +134 -0
  71. package/gateway/core/semver_classifier.py +152 -0
  72. package/gateway/core/spec_detector.py +130 -0
  73. package/gateway/core/surface_bridge.py +307 -0
  74. package/gateway/core/zero_spec/__init__.py +4 -0
  75. package/gateway/core/zero_spec/__pycache__/__init__.cpython-310.pyc +0 -0
  76. package/gateway/core/zero_spec/__pycache__/detector.cpython-310.pyc +0 -0
  77. package/gateway/core/zero_spec/__pycache__/express_extractor.cpython-310.pyc +0 -0
  78. package/gateway/core/zero_spec/__pycache__/fastapi_extractor.cpython-310.pyc +0 -0
  79. package/gateway/core/zero_spec/__pycache__/nestjs_extractor.cpython-310.pyc +0 -0
  80. package/gateway/core/zero_spec/detector.py +353 -0
  81. package/gateway/core/zero_spec/express_extractor.py +483 -0
  82. package/gateway/core/zero_spec/fastapi_extractor.py +254 -0
  83. package/gateway/core/zero_spec/nestjs_extractor.py +369 -0
  84. package/gateway/tasks/__init__.py +1 -0
  85. package/gateway/tasks/__pycache__/__init__.cpython-310.pyc +0 -0
  86. package/gateway/tasks/__pycache__/check_policy.cpython-310.pyc +0 -0
  87. package/gateway/tasks/__pycache__/check_policy_v2.cpython-310.pyc +0 -0
  88. package/gateway/tasks/__pycache__/check_policy_v3.cpython-310.pyc +0 -0
  89. package/gateway/tasks/__pycache__/explain_diff.cpython-310.pyc +0 -0
  90. package/gateway/tasks/__pycache__/explain_diff_v2.cpython-310.pyc +0 -0
  91. package/gateway/tasks/__pycache__/validate_api.cpython-310.pyc +0 -0
  92. package/gateway/tasks/__pycache__/validate_api_v2.cpython-310.pyc +0 -0
  93. package/gateway/tasks/__pycache__/validate_api_v3.cpython-310.pyc +0 -0
  94. package/gateway/tasks/check_policy.py +177 -0
  95. package/gateway/tasks/check_policy_v2.py +255 -0
  96. package/gateway/tasks/check_policy_v3.py +255 -0
  97. package/gateway/tasks/explain_diff.py +305 -0
  98. package/gateway/tasks/explain_diff_v2.py +267 -0
  99. package/gateway/tasks/validate_api.py +131 -0
  100. package/gateway/tasks/validate_api_v2.py +208 -0
  101. package/gateway/tasks/validate_api_v3.py +163 -0
  102. package/package.json +4 -3
  103. package/adapters/codex-skill.js +0 -87
  104. package/adapters/cursor-extension.js +0 -190
  105. package/adapters/gemini-action.js +0 -93
  106. package/adapters/openai-function.js +0 -112
  107. package/adapters/xai-plugin.js +0 -151
  108. package/test-decision-engine.js +0 -181
  109. package/test-hook.js +0 -27
  110. package/tests/cli.test.js +0 -359
  111. package/tests/fixtures/openapi-changed.yaml +0 -56
  112. package/tests/fixtures/openapi.yaml +0 -87
@@ -1,190 +0,0 @@
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
- }
@@ -1,93 +0,0 @@
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
- }
@@ -1,112 +0,0 @@
1
- #!/usr/bin/env node
2
- /**
3
- * Delimit™ OpenAI Function Adapter
4
- * Implements OpenAI Functions/Tools 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 DelimitOpenAIFunction {
11
- constructor() {
12
- this.name = 'delimit_governance_check';
13
- this.description = 'Check governance compliance for code operations';
14
- }
15
-
16
- /**
17
- * OpenAI Functions are called as tools
18
- */
19
- async execute(args) {
20
- console.log('[DELIMIT OPENAI] Function called with:', args);
21
-
22
- try {
23
- const { action, context } = args;
24
-
25
- // Validate the action
26
- const response = await axios.post(`${AGENT_URL}/evaluate`, {
27
- action: action || 'openai_function',
28
- context: context,
29
- tool: 'openai'
30
- });
31
-
32
- return {
33
- allowed: response.data.action !== 'block',
34
- action: response.data.action,
35
- message: response.data.message || 'Check complete',
36
- rule: response.data.rule
37
- };
38
- } catch (error) {
39
- console.warn('[DELIMIT OPENAI] Governance check failed:', error.message);
40
- return {
41
- allowed: true,
42
- message: 'Governance unavailable, proceeding with caution'
43
- };
44
- }
45
- }
46
-
47
- /**
48
- * OpenAI Plugins interface
49
- */
50
- async handleRequest(request) {
51
- const { method, path, body } = request;
52
-
53
- if (path === '/governance/check') {
54
- return await this.execute(body);
55
- }
56
-
57
- if (path === '/governance/status') {
58
- const { execSync } = require('child_process');
59
- const status = execSync('delimit status --json').toString();
60
- return JSON.parse(status);
61
- }
62
-
63
- if (path === '/governance/audit') {
64
- const { execSync } = require('child_process');
65
- const audit = execSync('delimit audit --json').toString();
66
- return JSON.parse(audit);
67
- }
68
-
69
- return { error: 'Unknown endpoint' };
70
- }
71
-
72
- /**
73
- * Tool definition for OpenAI
74
- */
75
- toToolDefinition() {
76
- return {
77
- type: 'function',
78
- function: {
79
- name: this.name,
80
- description: this.description,
81
- parameters: {
82
- type: 'object',
83
- properties: {
84
- action: {
85
- type: 'string',
86
- description: 'The action to validate'
87
- },
88
- context: {
89
- type: 'object',
90
- description: 'Context for validation',
91
- properties: {
92
- code: { type: 'string' },
93
- language: { type: 'string' },
94
- file: { type: 'string' },
95
- operation: { type: 'string' }
96
- }
97
- }
98
- },
99
- required: ['action']
100
- }
101
- }
102
- };
103
- }
104
- }
105
-
106
- // Export for OpenAI
107
- module.exports = new DelimitOpenAIFunction();
108
-
109
- // OpenAI registration (if available)
110
- if (typeof registerFunction === 'function') {
111
- registerFunction(new DelimitOpenAIFunction());
112
- }
@@ -1,151 +0,0 @@
1
- #!/usr/bin/env node
2
- /**
3
- * Delimit™ xAI Grok Plugin Adapter
4
- * Implements xAI Plugin 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 DelimitXAIPlugin {
11
- constructor() {
12
- this.name = 'delimit-governance';
13
- this.version = '2.0.0';
14
- this.capabilities = ['code_validation', 'security_check', 'audit_logging'];
15
- }
16
-
17
- /**
18
- * xAI Plugins use hooks for different stages
19
- */
20
- async prePrompt(context) {
21
- console.log('[DELIMIT XAI] Pre-prompt validation...');
22
-
23
- try {
24
- const { prompt, session, user } = context;
25
-
26
- // Check for risky prompts
27
- const riskyPatterns = [
28
- /sudo/i,
29
- /rm\s+-rf/i,
30
- /password/i,
31
- /credential/i,
32
- /secret/i
33
- ];
34
-
35
- const isRisky = riskyPatterns.some(pattern => pattern.test(prompt));
36
-
37
- if (isRisky) {
38
- const response = await axios.post(`${AGENT_URL}/evaluate`, {
39
- action: 'xai_prompt',
40
- prompt: prompt,
41
- riskLevel: 'high',
42
- session: session,
43
- tool: 'xai'
44
- });
45
-
46
- if (response.data.action === 'block') {
47
- return {
48
- block: true,
49
- message: `[DELIMIT] Prompt blocked: ${response.data.reason}`
50
- };
51
- }
52
-
53
- if (response.data.action === 'prompt') {
54
- return {
55
- warning: response.data.message
56
- };
57
- }
58
- }
59
-
60
- return { allow: true };
61
- } catch (error) {
62
- console.warn('[DELIMIT XAI] Governance check failed:', error.message);
63
- return { allow: true }; // Fail open
64
- }
65
- }
66
-
67
- async postResponse(context) {
68
- console.log('[DELIMIT XAI] Post-response processing...');
69
-
70
- try {
71
- const { response, session, metrics } = context;
72
-
73
- // Collect evidence
74
- await axios.post(`${AGENT_URL}/audit`, {
75
- action: 'xai_response',
76
- session: session,
77
- metrics: metrics,
78
- timestamp: new Date().toISOString()
79
- });
80
-
81
- // Check for sensitive data in response
82
- const sensitivePatterns = [
83
- /\b[A-Z0-9]{20,}\b/g, // API keys
84
- /-----BEGIN.*KEY-----/g, // Private keys
85
- /Bearer\s+[A-Za-z0-9\-._~+\/]+=*/g // Bearer tokens
86
- ];
87
-
88
- for (const pattern of sensitivePatterns) {
89
- if (pattern.test(response)) {
90
- console.warn('[DELIMIT XAI] ⚠️ Sensitive data detected in response');
91
- // Could redact or block here
92
- }
93
- }
94
- } catch (error) {
95
- // Silent fail for audit
96
- }
97
-
98
- return context;
99
- }
100
-
101
- async validateCode(code, language) {
102
- console.log('[DELIMIT XAI] Validating code...');
103
-
104
- try {
105
- const response = await axios.post(`${AGENT_URL}/evaluate`, {
106
- action: 'code_validation',
107
- code: code,
108
- language: language,
109
- tool: 'xai'
110
- });
111
-
112
- return {
113
- valid: response.data.action !== 'block',
114
- issues: response.data.issues || [],
115
- message: response.data.message
116
- };
117
- } catch (error) {
118
- return { valid: true, message: 'Validation unavailable' };
119
- }
120
- }
121
-
122
- // xAI command interface
123
- async executeCommand(command, args) {
124
- const commands = {
125
- 'governance': () => this.runCLI('status'),
126
- 'audit': () => this.runCLI('audit'),
127
- 'mode': () => this.runCLI('mode', args),
128
- 'policy': () => this.runCLI('policy')
129
- };
130
-
131
- if (commands[command]) {
132
- return await commands[command]();
133
- }
134
-
135
- return `Unknown command: ${command}`;
136
- }
137
-
138
- runCLI(command, args = []) {
139
- const { execSync } = require('child_process');
140
- const cmd = `delimit ${command} ${args.join(' ')}`.trim();
141
- return execSync(cmd).toString();
142
- }
143
- }
144
-
145
- // Export for xAI
146
- module.exports = new DelimitXAIPlugin();
147
-
148
- // xAI registration
149
- if (typeof registerPlugin === 'function') {
150
- registerPlugin(new DelimitXAIPlugin());
151
- }