@thispointon/kondi-chat 0.1.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/LICENSE +21 -0
- package/README.md +556 -0
- package/bin/kondi-chat +56 -0
- package/bin/kondi-chat.js +72 -0
- package/package.json +55 -0
- package/scripts/demo.tape +49 -0
- package/scripts/postinstall.cjs +103 -0
- package/src/audit/analytics.ts +261 -0
- package/src/audit/ledger.ts +253 -0
- package/src/audit/telemetry.ts +165 -0
- package/src/cli/backend.ts +675 -0
- package/src/cli/commands.ts +419 -0
- package/src/cli/help.ts +182 -0
- package/src/cli/submit-helpers.ts +159 -0
- package/src/cli/submit.ts +539 -0
- package/src/cli/wizard.ts +121 -0
- package/src/context/bootstrap.ts +138 -0
- package/src/context/budget.ts +100 -0
- package/src/context/manager.ts +666 -0
- package/src/context/memory.ts +160 -0
- package/src/context/preflight.ts +176 -0
- package/src/context/project-brain.ts +101 -0
- package/src/context/receipts.ts +108 -0
- package/src/context/skills.ts +154 -0
- package/src/context/symbol-index.ts +240 -0
- package/src/council/profiles.ts +137 -0
- package/src/council/tool.ts +138 -0
- package/src/council-engine/cli/council-artifacts.ts +230 -0
- package/src/council-engine/cli/council-config.ts +178 -0
- package/src/council-engine/cli/council-session-export.ts +116 -0
- package/src/council-engine/cli/kondi.ts +98 -0
- package/src/council-engine/cli/llm-caller.ts +229 -0
- package/src/council-engine/cli/localStorage-shim.ts +119 -0
- package/src/council-engine/cli/node-platform.ts +68 -0
- package/src/council-engine/cli/run-council.ts +481 -0
- package/src/council-engine/cli/run-pipeline.ts +772 -0
- package/src/council-engine/cli/session-export.ts +153 -0
- package/src/council-engine/configs/councils/analysis.json +101 -0
- package/src/council-engine/configs/councils/code-planning.json +86 -0
- package/src/council-engine/configs/councils/coding.json +89 -0
- package/src/council-engine/configs/councils/debate.json +97 -0
- package/src/council-engine/configs/councils/solo-claude.json +34 -0
- package/src/council-engine/configs/councils/solo-gpt.json +34 -0
- package/src/council-engine/council/coding-orchestrator.ts +1205 -0
- package/src/council-engine/council/context-bootstrap.ts +147 -0
- package/src/council-engine/council/context-inspection.ts +42 -0
- package/src/council-engine/council/context-store.ts +763 -0
- package/src/council-engine/council/deliberation-orchestrator.ts +2762 -0
- package/src/council-engine/council/factory.ts +164 -0
- package/src/council-engine/council/index.ts +201 -0
- package/src/council-engine/council/ledger-store.ts +438 -0
- package/src/council-engine/council/prompts.ts +1689 -0
- package/src/council-engine/council/storage-cleanup.ts +164 -0
- package/src/council-engine/council/store.ts +1110 -0
- package/src/council-engine/council/synthesis.ts +291 -0
- package/src/council-engine/council/types.ts +845 -0
- package/src/council-engine/council/validation.ts +613 -0
- package/src/council-engine/pipeline/build-detect.ts +73 -0
- package/src/council-engine/pipeline/executor.ts +1048 -0
- package/src/council-engine/pipeline/index.ts +9 -0
- package/src/council-engine/pipeline/install-detect.ts +84 -0
- package/src/council-engine/pipeline/memory-store.ts +182 -0
- package/src/council-engine/pipeline/output-parsers.ts +146 -0
- package/src/council-engine/pipeline/run-output.ts +149 -0
- package/src/council-engine/pipeline/session-import.ts +177 -0
- package/src/council-engine/pipeline/store.ts +753 -0
- package/src/council-engine/pipeline/test-detect.ts +82 -0
- package/src/council-engine/pipeline/types.ts +401 -0
- package/src/council-engine/services/deliberationSummary.ts +114 -0
- package/src/council-engine/tsconfig.json +16 -0
- package/src/council-engine/types/mcp.ts +122 -0
- package/src/council-engine/utils/filterTools.ts +73 -0
- package/src/engine/apply.ts +238 -0
- package/src/engine/checkpoints.ts +237 -0
- package/src/engine/consultants.ts +347 -0
- package/src/engine/diff.ts +171 -0
- package/src/engine/errors.ts +102 -0
- package/src/engine/git-tools.ts +246 -0
- package/src/engine/hooks.ts +181 -0
- package/src/engine/loop-guard.ts +155 -0
- package/src/engine/permissions.ts +293 -0
- package/src/engine/pipeline.ts +376 -0
- package/src/engine/sub-agents.ts +133 -0
- package/src/engine/task-card.ts +185 -0
- package/src/engine/task-router.ts +256 -0
- package/src/engine/task-store.ts +86 -0
- package/src/engine/tools.ts +783 -0
- package/src/engine/verify.ts +111 -0
- package/src/mcp/client.ts +225 -0
- package/src/mcp/config.ts +120 -0
- package/src/mcp/tool-manager.ts +192 -0
- package/src/mcp/types.ts +61 -0
- package/src/providers/llm-caller.ts +943 -0
- package/src/providers/rate-limiter.ts +238 -0
- package/src/router/NOTES.md +28 -0
- package/src/router/collector.ts +474 -0
- package/src/router/embeddings.ts +286 -0
- package/src/router/index.ts +299 -0
- package/src/router/intent-router.ts +225 -0
- package/src/router/nn-router.ts +205 -0
- package/src/router/profiles.ts +309 -0
- package/src/router/registry.ts +565 -0
- package/src/router/rules.ts +274 -0
- package/src/router/train.py +408 -0
- package/src/session/store.ts +211 -0
- package/src/test-utils/mock-llm.ts +39 -0
- package/src/types.ts +322 -0
- package/src/web/manager.ts +311 -0
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Directory Context Bootstrapping
|
|
3
|
+
* Scans a working directory to produce structured context for council deliberations.
|
|
4
|
+
*
|
|
5
|
+
* Node.js implementation (no Tauri dependency).
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { execSync } from 'node:child_process';
|
|
9
|
+
import { readFileSync, existsSync } from 'node:fs';
|
|
10
|
+
import { join, resolve } from 'node:path';
|
|
11
|
+
|
|
12
|
+
const MAX_FILE_SIZE = 2048; // chars per key file
|
|
13
|
+
const MAX_TOTAL_CHARS_DEFAULT = 10000;
|
|
14
|
+
const MAX_TOTAL_CHARS_DEEP = 120000; // ~30k tokens — enough for full source review
|
|
15
|
+
|
|
16
|
+
const KEY_FILES = [
|
|
17
|
+
'README.md',
|
|
18
|
+
'package.json',
|
|
19
|
+
'Cargo.toml',
|
|
20
|
+
'tsconfig.json',
|
|
21
|
+
'.env.example',
|
|
22
|
+
'pyproject.toml',
|
|
23
|
+
'go.mod',
|
|
24
|
+
'Makefile',
|
|
25
|
+
'docker-compose.yml',
|
|
26
|
+
'Dockerfile',
|
|
27
|
+
];
|
|
28
|
+
|
|
29
|
+
const KEY_ENTRY_PATTERNS = [
|
|
30
|
+
'src/index.ts', 'src/index.js', 'src/index.tsx',
|
|
31
|
+
'src/main.ts', 'src/main.js', 'src/main.tsx', 'src/main.rs',
|
|
32
|
+
'src/app.ts', 'src/app.js', 'src/App.tsx',
|
|
33
|
+
'src/lib.rs',
|
|
34
|
+
'main.go', 'main.py', 'app.py',
|
|
35
|
+
];
|
|
36
|
+
|
|
37
|
+
const SOURCE_EXTENSIONS = ['.ts', '.js', '.tsx', '.jsx', '.py', '.rs', '.go', '.java', '.rb'];
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Bootstrap directory context by scanning the working directory.
|
|
41
|
+
* When deep=true, reads all source files (for personas without tool access).
|
|
42
|
+
* Returns a formatted context block, or empty string if scanning fails.
|
|
43
|
+
*/
|
|
44
|
+
export async function bootstrapDirectoryContext(
|
|
45
|
+
workingDir: string,
|
|
46
|
+
options?: { maxFiles?: number; maxFileSize?: number; deep?: boolean }
|
|
47
|
+
): Promise<string> {
|
|
48
|
+
const maxFiles = options?.maxFiles ?? 80;
|
|
49
|
+
const maxFileSize = options?.maxFileSize ?? MAX_FILE_SIZE;
|
|
50
|
+
const deep = options?.deep ?? false;
|
|
51
|
+
const maxTotalChars = deep ? MAX_TOTAL_CHARS_DEEP : MAX_TOTAL_CHARS_DEFAULT;
|
|
52
|
+
|
|
53
|
+
try {
|
|
54
|
+
// Step 1: Get directory tree
|
|
55
|
+
let tree = '';
|
|
56
|
+
let fileList: string[] = [];
|
|
57
|
+
try {
|
|
58
|
+
const rawTree = execSync(
|
|
59
|
+
`find . -maxdepth 4 -type f -not -path '*/node_modules/*' -not -path '*/.git/*' -not -path '*/target/*' -not -path '*/__pycache__/*' -not -path '*/.next/*' -not -path '*/dist/*' -not -path '*/package-lock.json' | sort | head -${maxFiles}`,
|
|
60
|
+
{ cwd: workingDir, encoding: 'utf-8', timeout: 10_000 }
|
|
61
|
+
).trim();
|
|
62
|
+
tree = rawTree;
|
|
63
|
+
fileList = rawTree.split('\n').filter(Boolean);
|
|
64
|
+
} catch {
|
|
65
|
+
// find command failed, continue without tree
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
// Step 2: Read key files
|
|
69
|
+
const keyFileContents: Array<{ name: string; content: string }> = [];
|
|
70
|
+
let totalChars = tree.length + 200; // overhead for headers
|
|
71
|
+
|
|
72
|
+
const resolvedBase = resolve(workingDir);
|
|
73
|
+
|
|
74
|
+
// Key files first
|
|
75
|
+
const filesToTry = [...KEY_FILES, ...KEY_ENTRY_PATTERNS];
|
|
76
|
+
for (const fileName of filesToTry) {
|
|
77
|
+
if (totalChars >= maxTotalChars) break;
|
|
78
|
+
const content = safeReadFile(workingDir, resolvedBase, fileName, maxFileSize);
|
|
79
|
+
if (content) {
|
|
80
|
+
keyFileContents.push({ name: fileName, content });
|
|
81
|
+
totalChars += content.length + fileName.length + 20;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
// Step 3: In deep mode, read all source files from the tree
|
|
86
|
+
if (deep && fileList.length > 0) {
|
|
87
|
+
const sourceFiles = fileList.filter(f =>
|
|
88
|
+
SOURCE_EXTENSIONS.some(ext => f.endsWith(ext)) &&
|
|
89
|
+
!filesToTry.some(kf => f.endsWith(kf))
|
|
90
|
+
);
|
|
91
|
+
|
|
92
|
+
for (const relPath of sourceFiles) {
|
|
93
|
+
if (totalChars >= maxTotalChars) break;
|
|
94
|
+
const cleanPath = relPath.startsWith('./') ? relPath.slice(2) : relPath;
|
|
95
|
+
const deepMaxSize = Math.min(4096, maxTotalChars - totalChars);
|
|
96
|
+
if (deepMaxSize < 100) break;
|
|
97
|
+
const content = safeReadFile(workingDir, resolvedBase, cleanPath, deepMaxSize);
|
|
98
|
+
if (content) {
|
|
99
|
+
keyFileContents.push({ name: cleanPath, content });
|
|
100
|
+
totalChars += content.length + cleanPath.length + 20;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
// Step 4: Format output
|
|
106
|
+
if (!tree && keyFileContents.length === 0) {
|
|
107
|
+
return '';
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
const sections: string[] = [];
|
|
111
|
+
sections.push(`## Working Directory: ${workingDir}`);
|
|
112
|
+
|
|
113
|
+
if (tree) {
|
|
114
|
+
sections.push(`### Directory Structure\n\`\`\`\n${tree}\n\`\`\``);
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
if (keyFileContents.length > 0) {
|
|
118
|
+
sections.push('### Key Files');
|
|
119
|
+
for (const file of keyFileContents) {
|
|
120
|
+
sections.push(`#### ${file.name}\n\`\`\`\n${file.content}\n\`\`\``);
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
return sections.join('\n\n');
|
|
125
|
+
} catch (error) {
|
|
126
|
+
console.warn('[ContextBootstrap] Failed to bootstrap directory context:', error);
|
|
127
|
+
return '';
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
function safeReadFile(workingDir: string, resolvedBase: string, fileName: string, maxSize: number): string | null {
|
|
132
|
+
try {
|
|
133
|
+
const filePath = join(workingDir.replace(/\/$/, ''), fileName);
|
|
134
|
+
const resolvedPath = resolve(filePath);
|
|
135
|
+
if (!resolvedPath.startsWith(resolvedBase + '/') && resolvedPath !== resolvedBase) return null;
|
|
136
|
+
if (!existsSync(filePath)) return null;
|
|
137
|
+
|
|
138
|
+
const content = readFileSync(filePath, 'utf-8');
|
|
139
|
+
if (!content || content.length === 0) return null;
|
|
140
|
+
|
|
141
|
+
return content.length > maxSize
|
|
142
|
+
? content.slice(0, maxSize) + '\n... (truncated)'
|
|
143
|
+
: content;
|
|
144
|
+
} catch {
|
|
145
|
+
return null;
|
|
146
|
+
}
|
|
147
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Context Inspection: builds a summary of what was sent to the LLM for each agent call.
|
|
3
|
+
* Stored on LedgerEntry.structured.contextInspection for UI display.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
export interface ContextInspection {
|
|
7
|
+
systemPromptChars: number;
|
|
8
|
+
systemPromptSource: string;
|
|
9
|
+
userMessageChars: number;
|
|
10
|
+
toolScope: 'full' | 'plan' | 'read_only' | 'manager' | 'none';
|
|
11
|
+
toolCount: number;
|
|
12
|
+
toolNames?: string[];
|
|
13
|
+
effectiveServerIds?: string[];
|
|
14
|
+
wordLimitApplied?: number;
|
|
15
|
+
contextTokenBudget?: number;
|
|
16
|
+
timeoutMs?: number;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export function buildContextInspection(params: {
|
|
20
|
+
systemPrompt: string;
|
|
21
|
+
systemPromptSource: string;
|
|
22
|
+
userMessage: string;
|
|
23
|
+
toolScope: ContextInspection['toolScope'];
|
|
24
|
+
toolNames?: string[];
|
|
25
|
+
effectiveServerIds?: string[];
|
|
26
|
+
wordLimitApplied?: number;
|
|
27
|
+
contextTokenBudget?: number;
|
|
28
|
+
timeoutMs?: number;
|
|
29
|
+
}): ContextInspection {
|
|
30
|
+
return {
|
|
31
|
+
systemPromptChars: params.systemPrompt.length,
|
|
32
|
+
systemPromptSource: params.systemPromptSource,
|
|
33
|
+
userMessageChars: params.userMessage.length,
|
|
34
|
+
toolScope: params.toolScope,
|
|
35
|
+
toolCount: params.toolNames?.length || 0,
|
|
36
|
+
toolNames: params.toolNames?.slice(0, 20), // cap to avoid bloat
|
|
37
|
+
effectiveServerIds: params.effectiveServerIds,
|
|
38
|
+
wordLimitApplied: params.wordLimitApplied,
|
|
39
|
+
contextTokenBudget: params.contextTokenBudget,
|
|
40
|
+
timeoutMs: params.timeoutMs,
|
|
41
|
+
};
|
|
42
|
+
}
|