@x-code-cli/core 0.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/dist/agent/loop.d.ts +19 -0
- package/dist/agent/loop.d.ts.map +1 -0
- package/dist/agent/loop.js +443 -0
- package/dist/agent/loop.js.map +1 -0
- package/dist/agent/messages.d.ts +8 -0
- package/dist/agent/messages.d.ts.map +1 -0
- package/dist/agent/messages.js +51 -0
- package/dist/agent/messages.js.map +1 -0
- package/dist/agent/plan-mode.d.ts +11 -0
- package/dist/agent/plan-mode.d.ts.map +1 -0
- package/dist/agent/plan-mode.js +37 -0
- package/dist/agent/plan-mode.js.map +1 -0
- package/dist/agent/pricing.d.ts +9 -0
- package/dist/agent/pricing.d.ts.map +1 -0
- package/dist/agent/pricing.js +47 -0
- package/dist/agent/pricing.js.map +1 -0
- package/dist/agent/system-prompt.d.ts +9 -0
- package/dist/agent/system-prompt.d.ts.map +1 -0
- package/dist/agent/system-prompt.js +93 -0
- package/dist/agent/system-prompt.js.map +1 -0
- package/dist/config/index.d.ts +28 -0
- package/dist/config/index.d.ts.map +1 -0
- package/dist/config/index.js +88 -0
- package/dist/config/index.js.map +1 -0
- package/dist/index.d.ts +20 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +24 -0
- package/dist/index.js.map +1 -0
- package/dist/knowledge/auto-memory.d.ts +36 -0
- package/dist/knowledge/auto-memory.d.ts.map +1 -0
- package/dist/knowledge/auto-memory.js +151 -0
- package/dist/knowledge/auto-memory.js.map +1 -0
- package/dist/knowledge/hooks.d.ts +3 -0
- package/dist/knowledge/hooks.d.ts.map +1 -0
- package/dist/knowledge/hooks.js +59 -0
- package/dist/knowledge/hooks.js.map +1 -0
- package/dist/knowledge/init.d.ts +8 -0
- package/dist/knowledge/init.d.ts.map +1 -0
- package/dist/knowledge/init.js +98 -0
- package/dist/knowledge/init.js.map +1 -0
- package/dist/knowledge/loader.d.ts +14 -0
- package/dist/knowledge/loader.d.ts.map +1 -0
- package/dist/knowledge/loader.js +130 -0
- package/dist/knowledge/loader.js.map +1 -0
- package/dist/knowledge/session.d.ts +11 -0
- package/dist/knowledge/session.d.ts.map +1 -0
- package/dist/knowledge/session.js +108 -0
- package/dist/knowledge/session.js.map +1 -0
- package/dist/permissions/index.d.ts +14 -0
- package/dist/permissions/index.d.ts.map +1 -0
- package/dist/permissions/index.js +46 -0
- package/dist/permissions/index.js.map +1 -0
- package/dist/providers/registry.d.ts +2 -0
- package/dist/providers/registry.d.ts.map +1 -0
- package/dist/providers/registry.js +46 -0
- package/dist/providers/registry.js.map +1 -0
- package/dist/tools/ask-user.d.ts +8 -0
- package/dist/tools/ask-user.d.ts.map +1 -0
- package/dist/tools/ask-user.js +19 -0
- package/dist/tools/ask-user.js.map +1 -0
- package/dist/tools/edit.d.ts +7 -0
- package/dist/tools/edit.d.ts.map +1 -0
- package/dist/tools/edit.js +14 -0
- package/dist/tools/edit.js.map +1 -0
- package/dist/tools/enter-plan-mode.d.ts +2 -0
- package/dist/tools/enter-plan-mode.d.ts.map +1 -0
- package/dist/tools/enter-plan-mode.js +11 -0
- package/dist/tools/enter-plan-mode.js.map +1 -0
- package/dist/tools/exit-plan-mode.d.ts +2 -0
- package/dist/tools/exit-plan-mode.d.ts.map +1 -0
- package/dist/tools/exit-plan-mode.js +9 -0
- package/dist/tools/exit-plan-mode.js.map +1 -0
- package/dist/tools/glob.d.ts +5 -0
- package/dist/tools/glob.d.ts.map +1 -0
- package/dist/tools/glob.js +28 -0
- package/dist/tools/glob.js.map +1 -0
- package/dist/tools/grep.d.ts +7 -0
- package/dist/tools/grep.d.ts.map +1 -0
- package/dist/tools/grep.js +54 -0
- package/dist/tools/grep.js.map +1 -0
- package/dist/tools/index.d.ts +77 -0
- package/dist/tools/index.d.ts.map +1 -0
- package/dist/tools/index.js +41 -0
- package/dist/tools/index.js.map +1 -0
- package/dist/tools/list-dir.d.ts +4 -0
- package/dist/tools/list-dir.d.ts.map +1 -0
- package/dist/tools/list-dir.js +25 -0
- package/dist/tools/list-dir.js.map +1 -0
- package/dist/tools/read-file.d.ts +6 -0
- package/dist/tools/read-file.d.ts.map +1 -0
- package/dist/tools/read-file.js +28 -0
- package/dist/tools/read-file.js.map +1 -0
- package/dist/tools/save-knowledge.d.ts +8 -0
- package/dist/tools/save-knowledge.d.ts.map +1 -0
- package/dist/tools/save-knowledge.js +36 -0
- package/dist/tools/save-knowledge.js.map +1 -0
- package/dist/tools/shell-utils.d.ts +14 -0
- package/dist/tools/shell-utils.d.ts.map +1 -0
- package/dist/tools/shell-utils.js +111 -0
- package/dist/tools/shell-utils.js.map +1 -0
- package/dist/tools/shell.d.ts +5 -0
- package/dist/tools/shell.d.ts.map +1 -0
- package/dist/tools/shell.js +12 -0
- package/dist/tools/shell.js.map +1 -0
- package/dist/tools/web-fetch.d.ts +5 -0
- package/dist/tools/web-fetch.d.ts.map +1 -0
- package/dist/tools/web-fetch.js +59 -0
- package/dist/tools/web-fetch.js.map +1 -0
- package/dist/tools/web-search.d.ts +5 -0
- package/dist/tools/web-search.d.ts.map +1 -0
- package/dist/tools/web-search.js +27 -0
- package/dist/tools/web-search.js.map +1 -0
- package/dist/tools/write-file.d.ts +5 -0
- package/dist/tools/write-file.d.ts.map +1 -0
- package/dist/tools/write-file.js +12 -0
- package/dist/tools/write-file.js.map +1 -0
- package/dist/types/index.d.ts +108 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +36 -0
- package/dist/types/index.js.map +1 -0
- package/dist/utils.d.ts +9 -0
- package/dist/utils.d.ts.map +1 -0
- package/dist/utils.js +34 -0
- package/dist/utils.js.map +1 -0
- package/package.json +42 -0
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
interface InitResult {
|
|
2
|
+
detectedFacts: string[];
|
|
3
|
+
createdFiles: string[];
|
|
4
|
+
}
|
|
5
|
+
/** Initialize .x-code/ project structure and generate knowledge from project analysis */
|
|
6
|
+
export declare function initProject(cwd?: string): Promise<InitResult>;
|
|
7
|
+
export {};
|
|
8
|
+
//# sourceMappingURL=init.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../src/knowledge/init.ts"],"names":[],"mappings":"AAQA,UAAU,UAAU;IAClB,aAAa,EAAE,MAAM,EAAE,CAAA;IACvB,YAAY,EAAE,MAAM,EAAE,CAAA;CACvB;AAED,yFAAyF;AACzF,wBAAsB,WAAW,CAAC,GAAG,GAAE,MAAsB,GAAG,OAAO,CAAC,UAAU,CAAC,CAoFlF"}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
// @x-code/core — Project initialization (xc init / /init)
|
|
2
|
+
import fs from 'node:fs/promises';
|
|
3
|
+
import path from 'node:path';
|
|
4
|
+
import { XCODE_DIR, fileExists } from '../utils.js';
|
|
5
|
+
import { getAutoMemory } from './auto-memory.js';
|
|
6
|
+
import { scanProject } from './hooks.js';
|
|
7
|
+
/** Initialize .x-code/ project structure and generate knowledge from project analysis */
|
|
8
|
+
export async function initProject(cwd = process.cwd()) {
|
|
9
|
+
const xDir = path.join(cwd, XCODE_DIR);
|
|
10
|
+
const detectedFacts = [];
|
|
11
|
+
const createdFiles = [];
|
|
12
|
+
// Create directories
|
|
13
|
+
const dirs = [
|
|
14
|
+
xDir,
|
|
15
|
+
path.join(xDir, 'memory'),
|
|
16
|
+
path.join(xDir, 'rules'),
|
|
17
|
+
path.join(xDir, 'sessions'),
|
|
18
|
+
path.join(xDir, 'plans'),
|
|
19
|
+
path.join(xDir, 'local'),
|
|
20
|
+
];
|
|
21
|
+
for (const dir of dirs) {
|
|
22
|
+
await fs.mkdir(dir, { recursive: true });
|
|
23
|
+
}
|
|
24
|
+
// Scan project and populate auto memory
|
|
25
|
+
await scanProject(cwd);
|
|
26
|
+
const memory = getAutoMemory('project');
|
|
27
|
+
const facts = memory.getAll();
|
|
28
|
+
for (const fact of facts) {
|
|
29
|
+
detectedFacts.push(`${fact.key}: ${fact.fact}`);
|
|
30
|
+
}
|
|
31
|
+
// Generate knowledge.md
|
|
32
|
+
const knowledgePath = path.join(xDir, 'knowledge.md');
|
|
33
|
+
const knowledgeExists = await fileExists(knowledgePath);
|
|
34
|
+
if (!knowledgeExists) {
|
|
35
|
+
const knowledgeContent = generateKnowledgeMd(facts.map((f) => ({ key: f.key, fact: f.fact, category: f.category })));
|
|
36
|
+
await fs.writeFile(knowledgePath, knowledgeContent, 'utf-8');
|
|
37
|
+
createdFiles.push('.x-code/knowledge.md');
|
|
38
|
+
}
|
|
39
|
+
// Create .x-code/local/.gitignore if not exists
|
|
40
|
+
const localGitignore = path.join(xDir, 'local', '.gitignore');
|
|
41
|
+
if (!(await fileExists(localGitignore))) {
|
|
42
|
+
await fs.writeFile(localGitignore, '*\n', 'utf-8');
|
|
43
|
+
createdFiles.push('.x-code/local/.gitignore');
|
|
44
|
+
}
|
|
45
|
+
// Create .x-code/local/preferences.md template if not exists
|
|
46
|
+
const prefsPath = path.join(xDir, 'local', 'preferences.md');
|
|
47
|
+
if (!(await fileExists(prefsPath))) {
|
|
48
|
+
await fs.writeFile(prefsPath, '# Personal Preferences\n\n<!-- Add your personal coding preferences here. This file is gitignored. -->\n', 'utf-8');
|
|
49
|
+
createdFiles.push('.x-code/local/preferences.md');
|
|
50
|
+
}
|
|
51
|
+
// Ensure rules dir has a README
|
|
52
|
+
const rulesReadme = path.join(xDir, 'rules', 'README.md');
|
|
53
|
+
if (!(await fileExists(rulesReadme))) {
|
|
54
|
+
await fs.writeFile(rulesReadme, `# Rules
|
|
55
|
+
|
|
56
|
+
Place \`.md\` rule files here. Each rule supports optional frontmatter:
|
|
57
|
+
|
|
58
|
+
\`\`\`yaml
|
|
59
|
+
---
|
|
60
|
+
alwaysApply: true # Always load into context
|
|
61
|
+
paths: ["src/**/*.ts"] # Load when matching files are active
|
|
62
|
+
description: "..." # Listed for agent to request on demand
|
|
63
|
+
---
|
|
64
|
+
\`\`\`
|
|
65
|
+
|
|
66
|
+
Rules without frontmatter can be loaded manually via \`@rule-name\` in chat.
|
|
67
|
+
`, 'utf-8');
|
|
68
|
+
createdFiles.push('.x-code/rules/README.md');
|
|
69
|
+
}
|
|
70
|
+
if (createdFiles.includes('.x-code/knowledge.md')) {
|
|
71
|
+
createdFiles.push('.x-code/memory/auto.md');
|
|
72
|
+
}
|
|
73
|
+
return { detectedFacts, createdFiles };
|
|
74
|
+
}
|
|
75
|
+
function generateKnowledgeMd(facts) {
|
|
76
|
+
const lines = [
|
|
77
|
+
'# Project Knowledge',
|
|
78
|
+
'',
|
|
79
|
+
'<!-- Auto-generated by xc init. Feel free to edit and add business context. -->',
|
|
80
|
+
'',
|
|
81
|
+
];
|
|
82
|
+
const byCategory = new Map();
|
|
83
|
+
for (const f of facts) {
|
|
84
|
+
const list = byCategory.get(f.category) ?? [];
|
|
85
|
+
list.push({ key: f.key, fact: f.fact });
|
|
86
|
+
byCategory.set(f.category, list);
|
|
87
|
+
}
|
|
88
|
+
for (const [category, items] of byCategory) {
|
|
89
|
+
lines.push(`## ${category}`);
|
|
90
|
+
for (const item of items) {
|
|
91
|
+
lines.push(`- **${item.key}**: ${item.fact}`);
|
|
92
|
+
}
|
|
93
|
+
lines.push('');
|
|
94
|
+
}
|
|
95
|
+
lines.push('## Business Context', '', '<!-- Describe your project purpose, domain, and any important conventions here. -->', '');
|
|
96
|
+
return lines.join('\n');
|
|
97
|
+
}
|
|
98
|
+
//# sourceMappingURL=init.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"init.js","sourceRoot":"","sources":["../../src/knowledge/init.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { RuleFile } from '../types/index.js';
|
|
2
|
+
/** Load all rule files from .x-code/rules/ */
|
|
3
|
+
declare function loadRuleFiles(): Promise<RuleFile[]>;
|
|
4
|
+
/** Check if a file path matches any of the glob patterns (simple matching) */
|
|
5
|
+
declare function matchesPath(filePath: string, patterns: string[]): boolean;
|
|
6
|
+
/** Build the full knowledge context for system prompt injection */
|
|
7
|
+
export declare function buildKnowledgeContext(options?: {
|
|
8
|
+
activeFilePaths?: string[];
|
|
9
|
+
sessionContext?: string;
|
|
10
|
+
/** Pre-loaded rules to avoid redundant disk reads */
|
|
11
|
+
rules?: RuleFile[];
|
|
12
|
+
}): Promise<string>;
|
|
13
|
+
export { loadRuleFiles, matchesPath };
|
|
14
|
+
//# sourceMappingURL=loader.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"loader.d.ts","sourceRoot":"","sources":["../../src/knowledge/loader.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,QAAQ,EAAmB,MAAM,mBAAmB,CAAA;AA+BlE,8CAA8C;AAC9C,iBAAe,aAAa,IAAI,OAAO,CAAC,QAAQ,EAAE,CAAC,CAelD;AAED,8EAA8E;AAC9E,iBAAS,WAAW,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,GAAG,OAAO,CAUlE;AAED,mEAAmE;AACnE,wBAAsB,qBAAqB,CAAC,OAAO,CAAC,EAAE;IACpD,eAAe,CAAC,EAAE,MAAM,EAAE,CAAA;IAC1B,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,qDAAqD;IACrD,KAAK,CAAC,EAAE,QAAQ,EAAE,CAAA;CACnB,GAAG,OAAO,CAAC,MAAM,CAAC,CAuElB;AAED,OAAO,EAAE,aAAa,EAAE,WAAW,EAAE,CAAA"}
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
// @x-code/core — Knowledge loader (layered loading + 4 rule loading modes)
|
|
2
|
+
import fs from 'node:fs/promises';
|
|
3
|
+
import os from 'node:os';
|
|
4
|
+
import path from 'node:path';
|
|
5
|
+
import { XCODE_DIR, readFileSafe } from '../utils.js';
|
|
6
|
+
import { getAutoMemory } from './auto-memory.js';
|
|
7
|
+
const GLOBAL_DIR = path.join(os.homedir(), '.xcode');
|
|
8
|
+
/** Parse frontmatter from a markdown rule file */
|
|
9
|
+
function parseFrontmatter(content) {
|
|
10
|
+
const match = content.match(/^---\n([\s\S]*?)\n---\n([\s\S]*)$/);
|
|
11
|
+
if (!match)
|
|
12
|
+
return { frontmatter: {}, body: content };
|
|
13
|
+
const frontmatter = {};
|
|
14
|
+
const yamlLines = match[1].split('\n');
|
|
15
|
+
for (const line of yamlLines) {
|
|
16
|
+
const kvMatch = line.match(/^(\w+):\s*(.+)$/);
|
|
17
|
+
if (!kvMatch)
|
|
18
|
+
continue;
|
|
19
|
+
const [, key, value] = kvMatch;
|
|
20
|
+
if (key === 'alwaysApply')
|
|
21
|
+
frontmatter.alwaysApply = value.trim() === 'true';
|
|
22
|
+
else if (key === 'description')
|
|
23
|
+
frontmatter.description = value.trim().replace(/^"(.*)"$/, '$1');
|
|
24
|
+
else if (key === 'paths') {
|
|
25
|
+
// Parse YAML array: ["glob1", "glob2"]
|
|
26
|
+
const arrayMatch = value.match(/\[(.+)\]/);
|
|
27
|
+
if (arrayMatch) {
|
|
28
|
+
frontmatter.paths = arrayMatch[1].split(',').map((p) => p.trim().replace(/^"(.*)"$/, '$1'));
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
return { frontmatter, body: match[2] };
|
|
33
|
+
}
|
|
34
|
+
/** Load all rule files from .x-code/rules/ */
|
|
35
|
+
async function loadRuleFiles() {
|
|
36
|
+
const rulesDir = path.join(process.cwd(), XCODE_DIR, 'rules');
|
|
37
|
+
try {
|
|
38
|
+
const files = await fs.readdir(rulesDir);
|
|
39
|
+
const rules = [];
|
|
40
|
+
for (const file of files) {
|
|
41
|
+
if (!file.endsWith('.md'))
|
|
42
|
+
continue;
|
|
43
|
+
const content = await readFileSafe(path.join(rulesDir, file));
|
|
44
|
+
const { frontmatter, body } = parseFrontmatter(content);
|
|
45
|
+
rules.push({ filename: file.replace('.md', ''), frontmatter, content: body });
|
|
46
|
+
}
|
|
47
|
+
return rules;
|
|
48
|
+
}
|
|
49
|
+
catch {
|
|
50
|
+
return [];
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
/** Check if a file path matches any of the glob patterns (simple matching) */
|
|
54
|
+
function matchesPath(filePath, patterns) {
|
|
55
|
+
for (const pattern of patterns) {
|
|
56
|
+
// Simple glob matching: ** matches any path segment, * matches within segment
|
|
57
|
+
const regex = pattern
|
|
58
|
+
.replace(/\*\*/g, '___DOUBLESTAR___')
|
|
59
|
+
.replace(/\*/g, '[^/]*')
|
|
60
|
+
.replace(/___DOUBLESTAR___/g, '.*');
|
|
61
|
+
if (new RegExp(regex).test(filePath))
|
|
62
|
+
return true;
|
|
63
|
+
}
|
|
64
|
+
return false;
|
|
65
|
+
}
|
|
66
|
+
/** Build the full knowledge context for system prompt injection */
|
|
67
|
+
export async function buildKnowledgeContext(options) {
|
|
68
|
+
const sections = [];
|
|
69
|
+
// 1. Global preferences
|
|
70
|
+
const globalKnowledge = await readFileSafe(path.join(GLOBAL_DIR, 'knowledge.md'));
|
|
71
|
+
if (globalKnowledge) {
|
|
72
|
+
sections.push('### Global Preferences\n' + globalKnowledge);
|
|
73
|
+
}
|
|
74
|
+
// 2. Global auto memory
|
|
75
|
+
const globalMemory = getAutoMemory('global');
|
|
76
|
+
const globalMemoryContent = globalMemory.getPromptContent();
|
|
77
|
+
if (globalMemoryContent) {
|
|
78
|
+
sections.push('### Global Auto Memory\n' + globalMemoryContent);
|
|
79
|
+
}
|
|
80
|
+
// 3. Project knowledge
|
|
81
|
+
const projectKnowledge = await readFileSafe(path.join(process.cwd(), XCODE_DIR, 'knowledge.md'));
|
|
82
|
+
if (projectKnowledge) {
|
|
83
|
+
sections.push('### Project Knowledge\n' + projectKnowledge);
|
|
84
|
+
}
|
|
85
|
+
// 4. Project auto memory
|
|
86
|
+
const projectMemory = getAutoMemory('project');
|
|
87
|
+
const projectMemoryContent = projectMemory.getPromptContent();
|
|
88
|
+
if (projectMemoryContent) {
|
|
89
|
+
sections.push('### Project Auto Memory\n' + projectMemoryContent);
|
|
90
|
+
}
|
|
91
|
+
// 5. Local preferences
|
|
92
|
+
const localPrefs = await readFileSafe(path.join(process.cwd(), XCODE_DIR, 'local', 'preferences.md'));
|
|
93
|
+
if (localPrefs) {
|
|
94
|
+
sections.push('### Local Preferences\n' + localPrefs);
|
|
95
|
+
}
|
|
96
|
+
// 6. Rules (4 loading modes)
|
|
97
|
+
const rules = options?.rules ?? (await loadRuleFiles());
|
|
98
|
+
// Always rules
|
|
99
|
+
for (const rule of rules) {
|
|
100
|
+
if (rule.frontmatter.alwaysApply) {
|
|
101
|
+
sections.push(`### Rule: ${rule.filename}\n${rule.content}`);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
// Path-match rules
|
|
105
|
+
if (options?.activeFilePaths?.length) {
|
|
106
|
+
for (const rule of rules) {
|
|
107
|
+
if (rule.frontmatter.paths?.length) {
|
|
108
|
+
const matched = options.activeFilePaths.some((fp) => matchesPath(fp, rule.frontmatter.paths));
|
|
109
|
+
if (matched) {
|
|
110
|
+
sections.push(`### Rule: ${rule.filename}\n${rule.content}`);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
// Agent-requested rules: just list descriptions so model can request
|
|
116
|
+
const requestableRules = rules.filter((r) => r.frontmatter.description && !r.frontmatter.alwaysApply);
|
|
117
|
+
if (requestableRules.length > 0) {
|
|
118
|
+
const list = requestableRules.map((r) => `- @${r.filename}: ${r.frontmatter.description}`).join('\n');
|
|
119
|
+
sections.push(`### Available Rules (mention @name to load)\n${list}`);
|
|
120
|
+
}
|
|
121
|
+
// 7. Session context
|
|
122
|
+
if (options?.sessionContext) {
|
|
123
|
+
sections.push(options.sessionContext);
|
|
124
|
+
}
|
|
125
|
+
if (sections.length === 0)
|
|
126
|
+
return '';
|
|
127
|
+
return '## Project Knowledge\n\n' + sections.join('\n\n');
|
|
128
|
+
}
|
|
129
|
+
export { loadRuleFiles, matchesPath };
|
|
130
|
+
//# sourceMappingURL=loader.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"loader.js","sourceRoot":"","sources":["../../src/knowledge/loader.ts"],"names":[],"mappings":"AAAA,2EAA2E;AAC3E,OAAO,EAAE,MAAM,kBAAkB,CAAA;AACjC,OAAO,EAAE,MAAM,SAAS,CAAA;AACxB,OAAO,IAAI,MAAM,WAAW,CAAA;AAG5B,OAAO,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AACrD,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAA;AAEhD,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,QAAQ,CAAC,CAAA;AAEpD,kDAAkD;AAClD,SAAS,gBAAgB,CAAC,OAAe;IACvC,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,mCAAmC,CAAC,CAAA;IAChE,IAAI,CAAC,KAAK;QAAE,OAAO,EAAE,WAAW,EAAE,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,CAAA;IAErD,MAAM,WAAW,GAAoB,EAAE,CAAA;IACvC,MAAM,SAAS,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAA;IACtC,KAAK,MAAM,IAAI,IAAI,SAAS,EAAE,CAAC;QAC7B,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,iBAAiB,CAAC,CAAA;QAC7C,IAAI,CAAC,OAAO;YAAE,SAAQ;QACtB,MAAM,CAAC,EAAE,GAAG,EAAE,KAAK,CAAC,GAAG,OAAO,CAAA;QAC9B,IAAI,GAAG,KAAK,aAAa;YAAE,WAAW,CAAC,WAAW,GAAG,KAAK,CAAC,IAAI,EAAE,KAAK,MAAM,CAAA;aACvE,IAAI,GAAG,KAAK,aAAa;YAAE,WAAW,CAAC,WAAW,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC,OAAO,CAAC,UAAU,EAAE,IAAI,CAAC,CAAA;aAC3F,IAAI,GAAG,KAAK,OAAO,EAAE,CAAC;YACzB,uCAAuC;YACvC,MAAM,UAAU,GAAG,KAAK,CAAC,KAAK,CAAC,UAAU,CAAC,CAAA;YAC1C,IAAI,UAAU,EAAE,CAAC;gBACf,WAAW,CAAC,KAAK,GAAG,UAAU,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,OAAO,CAAC,UAAU,EAAE,IAAI,CAAC,CAAC,CAAA;YAC7F,CAAC;QACH,CAAC;IACH,CAAC;IAED,OAAO,EAAE,WAAW,EAAE,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC,EAAE,CAAA;AACxC,CAAC;AAED,8CAA8C;AAC9C,KAAK,UAAU,aAAa;IAC1B,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,OAAO,CAAC,CAAA;IAC7D,IAAI,CAAC;QACH,MAAM,KAAK,GAAG,MAAM,EAAE,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAA;QACxC,MAAM,KAAK,GAAe,EAAE,CAAA;QAC5B,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;YACzB,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC;gBAAE,SAAQ;YACnC,MAAM,OAAO,GAAG,MAAM,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC,CAAA;YAC7D,MAAM,EAAE,WAAW,EAAE,IAAI,EAAE,GAAG,gBAAgB,CAAC,OAAO,CAAC,CAAA;YACvD,KAAK,CAAC,IAAI,CAAC,EAAE,QAAQ,EAAE,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,EAAE,WAAW,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAA;QAC/E,CAAC;QACD,OAAO,KAAK,CAAA;IACd,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,CAAA;IACX,CAAC;AACH,CAAC;AAED,8EAA8E;AAC9E,SAAS,WAAW,CAAC,QAAgB,EAAE,QAAkB;IACvD,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;QAC/B,8EAA8E;QAC9E,MAAM,KAAK,GAAG,OAAO;aAClB,OAAO,CAAC,OAAO,EAAE,kBAAkB,CAAC;aACpC,OAAO,CAAC,KAAK,EAAE,OAAO,CAAC;aACvB,OAAO,CAAC,mBAAmB,EAAE,IAAI,CAAC,CAAA;QACrC,IAAI,IAAI,MAAM,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC;YAAE,OAAO,IAAI,CAAA;IACnD,CAAC;IACD,OAAO,KAAK,CAAA;AACd,CAAC;AAED,mEAAmE;AACnE,MAAM,CAAC,KAAK,UAAU,qBAAqB,CAAC,OAK3C;IACC,MAAM,QAAQ,GAAa,EAAE,CAAA;IAE7B,wBAAwB;IACxB,MAAM,eAAe,GAAG,MAAM,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,cAAc,CAAC,CAAC,CAAA;IACjF,IAAI,eAAe,EAAE,CAAC;QACpB,QAAQ,CAAC,IAAI,CAAC,0BAA0B,GAAG,eAAe,CAAC,CAAA;IAC7D,CAAC;IAED,wBAAwB;IACxB,MAAM,YAAY,GAAG,aAAa,CAAC,QAAQ,CAAC,CAAA;IAC5C,MAAM,mBAAmB,GAAG,YAAY,CAAC,gBAAgB,EAAE,CAAA;IAC3D,IAAI,mBAAmB,EAAE,CAAC;QACxB,QAAQ,CAAC,IAAI,CAAC,0BAA0B,GAAG,mBAAmB,CAAC,CAAA;IACjE,CAAC;IAED,uBAAuB;IACvB,MAAM,gBAAgB,GAAG,MAAM,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,cAAc,CAAC,CAAC,CAAA;IAChG,IAAI,gBAAgB,EAAE,CAAC;QACrB,QAAQ,CAAC,IAAI,CAAC,yBAAyB,GAAG,gBAAgB,CAAC,CAAA;IAC7D,CAAC;IAED,yBAAyB;IACzB,MAAM,aAAa,GAAG,aAAa,CAAC,SAAS,CAAC,CAAA;IAC9C,MAAM,oBAAoB,GAAG,aAAa,CAAC,gBAAgB,EAAE,CAAA;IAC7D,IAAI,oBAAoB,EAAE,CAAC;QACzB,QAAQ,CAAC,IAAI,CAAC,2BAA2B,GAAG,oBAAoB,CAAC,CAAA;IACnE,CAAC;IAED,uBAAuB;IACvB,MAAM,UAAU,GAAG,MAAM,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,OAAO,EAAE,gBAAgB,CAAC,CAAC,CAAA;IACrG,IAAI,UAAU,EAAE,CAAC;QACf,QAAQ,CAAC,IAAI,CAAC,yBAAyB,GAAG,UAAU,CAAC,CAAA;IACvD,CAAC;IAED,6BAA6B;IAC7B,MAAM,KAAK,GAAG,OAAO,EAAE,KAAK,IAAI,CAAC,MAAM,aAAa,EAAE,CAAC,CAAA;IAEvD,eAAe;IACf,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,IAAI,IAAI,CAAC,WAAW,CAAC,WAAW,EAAE,CAAC;YACjC,QAAQ,CAAC,IAAI,CAAC,aAAa,IAAI,CAAC,QAAQ,KAAK,IAAI,CAAC,OAAO,EAAE,CAAC,CAAA;QAC9D,CAAC;IACH,CAAC;IAED,mBAAmB;IACnB,IAAI,OAAO,EAAE,eAAe,EAAE,MAAM,EAAE,CAAC;QACrC,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;YACzB,IAAI,IAAI,CAAC,WAAW,CAAC,KAAK,EAAE,MAAM,EAAE,CAAC;gBACnC,MAAM,OAAO,GAAG,OAAO,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,WAAW,CAAC,EAAE,EAAE,IAAI,CAAC,WAAW,CAAC,KAAM,CAAC,CAAC,CAAA;gBAC9F,IAAI,OAAO,EAAE,CAAC;oBACZ,QAAQ,CAAC,IAAI,CAAC,aAAa,IAAI,CAAC,QAAQ,KAAK,IAAI,CAAC,OAAO,EAAE,CAAC,CAAA;gBAC9D,CAAC;YACH,CAAC;QACH,CAAC;IACH,CAAC;IAED,qEAAqE;IACrE,MAAM,gBAAgB,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,CAAC,WAAW,IAAI,CAAC,CAAC,CAAC,WAAW,CAAC,WAAW,CAAC,CAAA;IACrG,IAAI,gBAAgB,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAChC,MAAM,IAAI,GAAG,gBAAgB,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,CAAC,QAAQ,KAAK,CAAC,CAAC,WAAW,CAAC,WAAW,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;QACrG,QAAQ,CAAC,IAAI,CAAC,gDAAgD,IAAI,EAAE,CAAC,CAAA;IACvE,CAAC;IAED,qBAAqB;IACrB,IAAI,OAAO,EAAE,cAAc,EAAE,CAAC;QAC5B,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,cAAc,CAAC,CAAA;IACvC,CAAC;IAED,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,EAAE,CAAA;IACpC,OAAO,0BAA0B,GAAG,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,CAAA;AAC3D,CAAC;AAED,OAAO,EAAE,aAAa,EAAE,WAAW,EAAE,CAAA"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { LanguageModel, ModelMessage } from 'ai';
|
|
2
|
+
import type { SessionSummary } from '../types/index.js';
|
|
3
|
+
/** Load the most recent session summary */
|
|
4
|
+
export declare function loadLatestSession(): Promise<SessionSummary | null>;
|
|
5
|
+
/** Save a session summary */
|
|
6
|
+
export declare function saveSessionSummary(summary: SessionSummary): Promise<void>;
|
|
7
|
+
/** Generate a session summary from messages using the model */
|
|
8
|
+
export declare function generateSessionSummary(messages: ModelMessage[], model: LanguageModel, sessionId: string, startedAt: string, filesModified: string[]): Promise<SessionSummary>;
|
|
9
|
+
/** Format session summary for system prompt injection */
|
|
10
|
+
export declare function formatSessionForPrompt(session: SessionSummary): string;
|
|
11
|
+
//# sourceMappingURL=session.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../../src/knowledge/session.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,IAAI,CAAA;AAErD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAA;AAevD,2CAA2C;AAC3C,wBAAsB,iBAAiB,IAAI,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC,CAOxE;AAED,6BAA6B;AAC7B,wBAAsB,kBAAkB,CAAC,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC,CAQ/E;AAED,+DAA+D;AAC/D,wBAAsB,sBAAsB,CAC1C,QAAQ,EAAE,YAAY,EAAE,EACxB,KAAK,EAAE,aAAa,EACpB,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,MAAM,EACjB,aAAa,EAAE,MAAM,EAAE,GACtB,OAAO,CAAC,cAAc,CAAC,CAgDzB;AAED,yDAAyD;AACzD,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,cAAc,GAAG,MAAM,CAoBtE"}
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
// @x-code/core — Session memory (structured JSON summaries for cross-session continuation)
|
|
2
|
+
import fs from 'node:fs/promises';
|
|
3
|
+
import path from 'node:path';
|
|
4
|
+
import { generateText } from 'ai';
|
|
5
|
+
import { XCODE_DIR } from '../utils.js';
|
|
6
|
+
const SESSIONS_DIR = `${XCODE_DIR}/sessions`;
|
|
7
|
+
/** Number of recent messages to include when generating session summaries */
|
|
8
|
+
const SESSION_SUMMARY_MESSAGE_COUNT = 20;
|
|
9
|
+
function getSessionsDir() {
|
|
10
|
+
return path.join(process.cwd(), SESSIONS_DIR);
|
|
11
|
+
}
|
|
12
|
+
function getLatestPath() {
|
|
13
|
+
return path.join(getSessionsDir(), 'latest.json');
|
|
14
|
+
}
|
|
15
|
+
/** Load the most recent session summary */
|
|
16
|
+
export async function loadLatestSession() {
|
|
17
|
+
try {
|
|
18
|
+
const raw = await fs.readFile(getLatestPath(), 'utf-8');
|
|
19
|
+
return JSON.parse(raw);
|
|
20
|
+
}
|
|
21
|
+
catch {
|
|
22
|
+
return null;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
/** Save a session summary */
|
|
26
|
+
export async function saveSessionSummary(summary) {
|
|
27
|
+
const dir = getSessionsDir();
|
|
28
|
+
await fs.mkdir(dir, { recursive: true });
|
|
29
|
+
await fs.writeFile(getLatestPath(), JSON.stringify(summary, null, 2), 'utf-8');
|
|
30
|
+
const archivePath = path.join(dir, `${summary.id}.json`);
|
|
31
|
+
await fs.writeFile(archivePath, JSON.stringify(summary, null, 2), 'utf-8');
|
|
32
|
+
}
|
|
33
|
+
/** Generate a session summary from messages using the model */
|
|
34
|
+
export async function generateSessionSummary(messages, model, sessionId, startedAt, filesModified) {
|
|
35
|
+
const { text } = await generateText({
|
|
36
|
+
model,
|
|
37
|
+
messages: [
|
|
38
|
+
{
|
|
39
|
+
role: 'system',
|
|
40
|
+
content: `Summarize this conversation as a structured JSON object with these fields:
|
|
41
|
+
- title: short descriptive title (string)
|
|
42
|
+
- summary: 2-3 sentence overview (string)
|
|
43
|
+
- keyResults: what was accomplished (string[])
|
|
44
|
+
- pendingWork: what remains to be done (string[])
|
|
45
|
+
- decisions: important decisions made (string[])
|
|
46
|
+
- status: "completed" | "in_progress" | "abandoned"
|
|
47
|
+
|
|
48
|
+
Return ONLY valid JSON, no markdown fencing.`,
|
|
49
|
+
},
|
|
50
|
+
...messages.slice(-SESSION_SUMMARY_MESSAGE_COUNT),
|
|
51
|
+
],
|
|
52
|
+
});
|
|
53
|
+
try {
|
|
54
|
+
const parsed = JSON.parse(text);
|
|
55
|
+
return {
|
|
56
|
+
id: sessionId,
|
|
57
|
+
startedAt,
|
|
58
|
+
endedAt: new Date().toISOString(),
|
|
59
|
+
filesModified,
|
|
60
|
+
title: parsed.title ?? 'Untitled session',
|
|
61
|
+
summary: parsed.summary ?? '',
|
|
62
|
+
keyResults: parsed.keyResults ?? [],
|
|
63
|
+
pendingWork: parsed.pendingWork ?? [],
|
|
64
|
+
decisions: parsed.decisions ?? [],
|
|
65
|
+
status: parsed.status ?? 'completed',
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
catch {
|
|
69
|
+
return {
|
|
70
|
+
id: sessionId,
|
|
71
|
+
startedAt,
|
|
72
|
+
endedAt: new Date().toISOString(),
|
|
73
|
+
title: 'Session',
|
|
74
|
+
summary: text.slice(0, 200),
|
|
75
|
+
keyResults: [],
|
|
76
|
+
pendingWork: [],
|
|
77
|
+
filesModified,
|
|
78
|
+
decisions: [],
|
|
79
|
+
status: 'completed',
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
/** Format session summary for system prompt injection */
|
|
84
|
+
export function formatSessionForPrompt(session) {
|
|
85
|
+
const lines = [
|
|
86
|
+
`### Previous Session`,
|
|
87
|
+
`Title: ${session.title}`,
|
|
88
|
+
`Status: ${session.status}`,
|
|
89
|
+
`Summary: ${session.summary}`,
|
|
90
|
+
];
|
|
91
|
+
if (session.keyResults.length > 0) {
|
|
92
|
+
lines.push('Key results:');
|
|
93
|
+
for (const r of session.keyResults)
|
|
94
|
+
lines.push(`- ${r}`);
|
|
95
|
+
}
|
|
96
|
+
if (session.pendingWork.length > 0) {
|
|
97
|
+
lines.push('Pending work:');
|
|
98
|
+
for (const w of session.pendingWork)
|
|
99
|
+
lines.push(`- ${w}`);
|
|
100
|
+
}
|
|
101
|
+
if (session.decisions.length > 0) {
|
|
102
|
+
lines.push('Decisions:');
|
|
103
|
+
for (const d of session.decisions)
|
|
104
|
+
lines.push(`- ${d}`);
|
|
105
|
+
}
|
|
106
|
+
return lines.join('\n');
|
|
107
|
+
}
|
|
108
|
+
//# sourceMappingURL=session.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session.js","sourceRoot":"","sources":["../../src/knowledge/session.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { PermissionLevel } from '../types/index.js';
|
|
2
|
+
type PermissionInput = Record<string, unknown>;
|
|
3
|
+
/** Get permission level for a tool call */
|
|
4
|
+
export declare function getPermissionLevel(toolName: string, input: PermissionInput): PermissionLevel;
|
|
5
|
+
/** Check permission with trust mode support */
|
|
6
|
+
export declare function checkPermission(toolCall: {
|
|
7
|
+
toolName: string;
|
|
8
|
+
input: PermissionInput;
|
|
9
|
+
}, trustMode: boolean, onAskPermission: (toolCall: {
|
|
10
|
+
toolName: string;
|
|
11
|
+
input: PermissionInput;
|
|
12
|
+
}) => Promise<boolean>): Promise<boolean>;
|
|
13
|
+
export {};
|
|
14
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/permissions/index.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAA;AAExD,KAAK,eAAe,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;AA6B9C,2CAA2C;AAC3C,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,eAAe,GAAG,eAAe,CAI5F;AAED,+CAA+C;AAC/C,wBAAsB,eAAe,CACnC,QAAQ,EAAE;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,eAAe,CAAA;CAAE,EACtD,SAAS,EAAE,OAAO,EAClB,eAAe,EAAE,CAAC,QAAQ,EAAE;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,eAAe,CAAA;CAAE,KAAK,OAAO,CAAC,OAAO,CAAC,GAC5F,OAAO,CAAC,OAAO,CAAC,CAKlB"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
// @x-code/core — Permission system (3-level model)
|
|
2
|
+
import { isDestructive, isReadOnly, splitShellCommands } from '../tools/shell-utils.js';
|
|
3
|
+
/** Permission rules for each tool */
|
|
4
|
+
const rules = {
|
|
5
|
+
readFile: () => 'always-allow',
|
|
6
|
+
glob: () => 'always-allow',
|
|
7
|
+
grep: () => 'always-allow',
|
|
8
|
+
listDir: () => 'always-allow',
|
|
9
|
+
webSearch: () => 'always-allow',
|
|
10
|
+
webFetch: () => 'always-allow',
|
|
11
|
+
askUser: () => 'always-allow',
|
|
12
|
+
saveKnowledge: () => 'always-allow',
|
|
13
|
+
edit: () => 'ask',
|
|
14
|
+
writeFile: () => 'ask',
|
|
15
|
+
enterPlanMode: () => 'always-allow',
|
|
16
|
+
exitPlanMode: () => 'always-allow',
|
|
17
|
+
shell: (input) => {
|
|
18
|
+
const cmd = input.command ?? '';
|
|
19
|
+
const subCommands = splitShellCommands(cmd);
|
|
20
|
+
// Any sub-command destructive → deny the whole command
|
|
21
|
+
if (subCommands.some(isDestructive))
|
|
22
|
+
return 'deny';
|
|
23
|
+
// All sub-commands read-only → auto-allow
|
|
24
|
+
if (subCommands.every(isReadOnly))
|
|
25
|
+
return 'always-allow';
|
|
26
|
+
// Otherwise → ask
|
|
27
|
+
return 'ask';
|
|
28
|
+
},
|
|
29
|
+
};
|
|
30
|
+
/** Get permission level for a tool call */
|
|
31
|
+
export function getPermissionLevel(toolName, input) {
|
|
32
|
+
const rule = rules[toolName];
|
|
33
|
+
if (!rule)
|
|
34
|
+
return 'ask'; // Unknown tool defaults to ask
|
|
35
|
+
return rule(input);
|
|
36
|
+
}
|
|
37
|
+
/** Check permission with trust mode support */
|
|
38
|
+
export async function checkPermission(toolCall, trustMode, onAskPermission) {
|
|
39
|
+
const level = getPermissionLevel(toolCall.toolName, toolCall.input);
|
|
40
|
+
if (level === 'deny')
|
|
41
|
+
return false;
|
|
42
|
+
if (level === 'always-allow' || trustMode)
|
|
43
|
+
return true;
|
|
44
|
+
return onAskPermission(toolCall);
|
|
45
|
+
}
|
|
46
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/permissions/index.ts"],"names":[],"mappings":"AAAA,mDAAmD;AACnD,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAA;AAKvF,qCAAqC;AACrC,MAAM,KAAK,GAAgE;IACzE,QAAQ,EAAE,GAAG,EAAE,CAAC,cAAc;IAC9B,IAAI,EAAE,GAAG,EAAE,CAAC,cAAc;IAC1B,IAAI,EAAE,GAAG,EAAE,CAAC,cAAc;IAC1B,OAAO,EAAE,GAAG,EAAE,CAAC,cAAc;IAC7B,SAAS,EAAE,GAAG,EAAE,CAAC,cAAc;IAC/B,QAAQ,EAAE,GAAG,EAAE,CAAC,cAAc;IAC9B,OAAO,EAAE,GAAG,EAAE,CAAC,cAAc;IAC7B,aAAa,EAAE,GAAG,EAAE,CAAC,cAAc;IACnC,IAAI,EAAE,GAAG,EAAE,CAAC,KAAK;IACjB,SAAS,EAAE,GAAG,EAAE,CAAC,KAAK;IACtB,aAAa,EAAE,GAAG,EAAE,CAAC,cAAc;IACnC,YAAY,EAAE,GAAG,EAAE,CAAC,cAAc;IAClC,KAAK,EAAE,CAAC,KAAK,EAAE,EAAE;QACf,MAAM,GAAG,GAAI,KAAK,CAAC,OAAkB,IAAI,EAAE,CAAA;QAC3C,MAAM,WAAW,GAAG,kBAAkB,CAAC,GAAG,CAAC,CAAA;QAE3C,uDAAuD;QACvD,IAAI,WAAW,CAAC,IAAI,CAAC,aAAa,CAAC;YAAE,OAAO,MAAM,CAAA;QAClD,0CAA0C;QAC1C,IAAI,WAAW,CAAC,KAAK,CAAC,UAAU,CAAC;YAAE,OAAO,cAAc,CAAA;QACxD,kBAAkB;QAClB,OAAO,KAAK,CAAA;IACd,CAAC;CACF,CAAA;AAED,2CAA2C;AAC3C,MAAM,UAAU,kBAAkB,CAAC,QAAgB,EAAE,KAAsB;IACzE,MAAM,IAAI,GAAG,KAAK,CAAC,QAAQ,CAAC,CAAA;IAC5B,IAAI,CAAC,IAAI;QAAE,OAAO,KAAK,CAAA,CAAC,+BAA+B;IACvD,OAAO,IAAI,CAAC,KAAK,CAAC,CAAA;AACpB,CAAC;AAED,+CAA+C;AAC/C,MAAM,CAAC,KAAK,UAAU,eAAe,CACnC,QAAsD,EACtD,SAAkB,EAClB,eAA6F;IAE7F,MAAM,KAAK,GAAG,kBAAkB,CAAC,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC,KAAK,CAAC,CAAA;IACnE,IAAI,KAAK,KAAK,MAAM;QAAE,OAAO,KAAK,CAAA;IAClC,IAAI,KAAK,KAAK,cAAc,IAAI,SAAS;QAAE,OAAO,IAAI,CAAA;IACtD,OAAO,eAAe,CAAC,QAAQ,CAAC,CAAA;AAClC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../src/providers/registry.ts"],"names":[],"mappings":"AAeA,wBAAgB,mBAAmB,oEA4BlC"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
// @x-code/core — AI SDK Provider Registry (multi-model support)
|
|
2
|
+
import { zhipu } from 'zhipu-ai-provider';
|
|
3
|
+
import { createAlibaba } from '@ai-sdk/alibaba';
|
|
4
|
+
import { anthropic } from '@ai-sdk/anthropic';
|
|
5
|
+
import { deepseek } from '@ai-sdk/deepseek';
|
|
6
|
+
import { google } from '@ai-sdk/google';
|
|
7
|
+
import { moonshotai } from '@ai-sdk/moonshotai';
|
|
8
|
+
import { createOpenAI } from '@ai-sdk/openai';
|
|
9
|
+
import { createOpenAICompatible } from '@ai-sdk/openai-compatible';
|
|
10
|
+
import { xai } from '@ai-sdk/xai';
|
|
11
|
+
import { createProviderRegistry } from 'ai';
|
|
12
|
+
import { getProviderOptions } from '../config/index.js';
|
|
13
|
+
export function createModelRegistry() {
|
|
14
|
+
const opts = getProviderOptions();
|
|
15
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
16
|
+
const providers = {};
|
|
17
|
+
if (opts.anthropic)
|
|
18
|
+
providers.anthropic = anthropic;
|
|
19
|
+
if (opts.openai)
|
|
20
|
+
providers.openai = createOpenAI();
|
|
21
|
+
if (opts.google)
|
|
22
|
+
providers.google = google;
|
|
23
|
+
if (opts.xai)
|
|
24
|
+
providers.xai = xai;
|
|
25
|
+
if (opts.deepseek)
|
|
26
|
+
providers.deepseek = deepseek;
|
|
27
|
+
if (opts.alibaba) {
|
|
28
|
+
providers.alibaba = createAlibaba({
|
|
29
|
+
baseURL: 'https://dashscope.aliyuncs.com/compatible-mode/v1',
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
if (opts.zhipu)
|
|
33
|
+
providers.zhipu = zhipu;
|
|
34
|
+
if (opts.moonshotai)
|
|
35
|
+
providers.moonshotai = moonshotai;
|
|
36
|
+
// Custom OpenAI compatible provider
|
|
37
|
+
if (opts.custom.apiKey && opts.custom.baseURL) {
|
|
38
|
+
providers.custom = createOpenAICompatible({
|
|
39
|
+
name: 'custom',
|
|
40
|
+
apiKey: opts.custom.apiKey,
|
|
41
|
+
baseURL: opts.custom.baseURL,
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
return createProviderRegistry(providers);
|
|
45
|
+
}
|
|
46
|
+
//# sourceMappingURL=registry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"registry.js","sourceRoot":"","sources":["../../src/providers/registry.ts"],"names":[],"mappings":"AAAA,gEAAgE;AAChE,OAAO,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAA;AAEzC,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAA;AAC/C,OAAO,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAA;AAC7C,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAA;AAC3C,OAAO,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAA;AACvC,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAA;AAC/C,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAA;AAC7C,OAAO,EAAE,sBAAsB,EAAE,MAAM,2BAA2B,CAAA;AAClE,OAAO,EAAE,GAAG,EAAE,MAAM,aAAa,CAAA;AACjC,OAAO,EAAE,sBAAsB,EAAE,MAAM,IAAI,CAAA;AAE3C,OAAO,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAA;AAEvD,MAAM,UAAU,mBAAmB;IACjC,MAAM,IAAI,GAAG,kBAAkB,EAAE,CAAA;IACjC,8DAA8D;IAC9D,MAAM,SAAS,GAAwB,EAAE,CAAA;IAEzC,IAAI,IAAI,CAAC,SAAS;QAAE,SAAS,CAAC,SAAS,GAAG,SAAS,CAAA;IACnD,IAAI,IAAI,CAAC,MAAM;QAAE,SAAS,CAAC,MAAM,GAAG,YAAY,EAAE,CAAA;IAClD,IAAI,IAAI,CAAC,MAAM;QAAE,SAAS,CAAC,MAAM,GAAG,MAAM,CAAA;IAC1C,IAAI,IAAI,CAAC,GAAG;QAAE,SAAS,CAAC,GAAG,GAAG,GAAG,CAAA;IACjC,IAAI,IAAI,CAAC,QAAQ;QAAE,SAAS,CAAC,QAAQ,GAAG,QAAQ,CAAA;IAChD,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;QACjB,SAAS,CAAC,OAAO,GAAG,aAAa,CAAC;YAChC,OAAO,EAAE,mDAAmD;SAC7D,CAAC,CAAA;IACJ,CAAC;IACD,IAAI,IAAI,CAAC,KAAK;QAAE,SAAS,CAAC,KAAK,GAAG,KAAK,CAAA;IACvC,IAAI,IAAI,CAAC,UAAU;QAAE,SAAS,CAAC,UAAU,GAAG,UAAU,CAAA;IAEtD,oCAAoC;IACpC,IAAI,IAAI,CAAC,MAAM,CAAC,MAAM,IAAI,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;QAC9C,SAAS,CAAC,MAAM,GAAG,sBAAsB,CAAC;YACxC,IAAI,EAAE,QAAQ;YACd,MAAM,EAAE,IAAI,CAAC,MAAM,CAAC,MAAM;YAC1B,OAAO,EAAE,IAAI,CAAC,MAAM,CAAC,OAAO;SAC7B,CAAC,CAAA;IACJ,CAAC;IAED,OAAO,sBAAsB,CAAC,SAAS,CAAC,CAAA;AAC1C,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ask-user.d.ts","sourceRoot":"","sources":["../../src/tools/ask-user.ts"],"names":[],"mappings":"AAKA,eAAO,MAAM,OAAO;;;;;;SAiBlB,CAAA"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
// @x-code/core — askUser tool (interactive question, no execute — handled via callback)
|
|
2
|
+
import { tool } from 'ai';
|
|
3
|
+
import { z } from 'zod';
|
|
4
|
+
export const askUser = tool({
|
|
5
|
+
description: 'Ask the user a clarifying question with multiple-choice options. Use when you need user input to decide between approaches.',
|
|
6
|
+
inputSchema: z.object({
|
|
7
|
+
question: z.string().describe('The question to ask'),
|
|
8
|
+
options: z
|
|
9
|
+
.array(z.object({
|
|
10
|
+
label: z.string().describe('Option label (1-5 words)'),
|
|
11
|
+
description: z.string().describe('What this option means'),
|
|
12
|
+
}))
|
|
13
|
+
.min(2)
|
|
14
|
+
.max(4)
|
|
15
|
+
.describe('Choices (an "Other" option is auto-appended)'),
|
|
16
|
+
}),
|
|
17
|
+
// No execute — through callback to trigger UI rendering
|
|
18
|
+
});
|
|
19
|
+
//# sourceMappingURL=ask-user.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ask-user.js","sourceRoot":"","sources":["../../src/tools/ask-user.ts"],"names":[],"mappings":"AAAA,wFAAwF;AACxF,OAAO,EAAE,IAAI,EAAE,MAAM,IAAI,CAAA;AAEzB,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAEvB,MAAM,CAAC,MAAM,OAAO,GAAG,IAAI,CAAC;IAC1B,WAAW,EACT,6HAA6H;IAC/H,WAAW,EAAE,CAAC,CAAC,MAAM,CAAC;QACpB,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,qBAAqB,CAAC;QACpD,OAAO,EAAE,CAAC;aACP,KAAK,CACJ,CAAC,CAAC,MAAM,CAAC;YACP,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,0BAA0B,CAAC;YACtD,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,wBAAwB,CAAC;SAC3D,CAAC,CACH;aACA,GAAG,CAAC,CAAC,CAAC;aACN,GAAG,CAAC,CAAC,CAAC;aACN,QAAQ,CAAC,8CAA8C,CAAC;KAC5D,CAAC;IACF,wDAAwD;CACzD,CAAC,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"edit.d.ts","sourceRoot":"","sources":["../../src/tools/edit.ts"],"names":[],"mappings":"AAKA,eAAO,MAAM,IAAI;;;;;SAUf,CAAA"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
// @x-code/core — edit tool (precise string replacement, no execute — needs permission check)
|
|
2
|
+
import { tool } from 'ai';
|
|
3
|
+
import { z } from 'zod';
|
|
4
|
+
export const edit = tool({
|
|
5
|
+
description: 'Replace a specific string in a file. The old_string must be unique in the file. Preferred over writeFile for modifications — safer and costs fewer tokens.',
|
|
6
|
+
inputSchema: z.object({
|
|
7
|
+
filePath: z.string().describe('Absolute path to the file'),
|
|
8
|
+
oldString: z.string().describe('The exact text to find and replace (must be unique in the file)'),
|
|
9
|
+
newString: z.string().describe('The replacement text'),
|
|
10
|
+
replaceAll: z.boolean().optional().describe('Replace all occurrences (default: false)'),
|
|
11
|
+
}),
|
|
12
|
+
// No execute — handled manually in agent loop for permission check
|
|
13
|
+
});
|
|
14
|
+
//# sourceMappingURL=edit.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"edit.js","sourceRoot":"","sources":["../../src/tools/edit.ts"],"names":[],"mappings":"AAAA,6FAA6F;AAC7F,OAAO,EAAE,IAAI,EAAE,MAAM,IAAI,CAAA;AAEzB,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAEvB,MAAM,CAAC,MAAM,IAAI,GAAG,IAAI,CAAC;IACvB,WAAW,EACT,4JAA4J;IAC9J,WAAW,EAAE,CAAC,CAAC,MAAM,CAAC;QACpB,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,2BAA2B,CAAC;QAC1D,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,iEAAiE,CAAC;QACjG,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,sBAAsB,CAAC;QACtD,UAAU,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,0CAA0C,CAAC;KACxF,CAAC;IACF,mEAAmE;CACpE,CAAC,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"enter-plan-mode.d.ts","sourceRoot":"","sources":["../../src/tools/enter-plan-mode.ts"],"names":[],"mappings":"AAKA,eAAO,MAAM,aAAa,8BAMxB,CAAA"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
// @x-code/core — enterPlanMode tool (no execute — handled in agent loop)
|
|
2
|
+
import { tool } from 'ai';
|
|
3
|
+
import { z } from 'zod';
|
|
4
|
+
export const enterPlanMode = tool({
|
|
5
|
+
description: `Enter plan mode for exploring the codebase and designing an implementation plan.
|
|
6
|
+
Use proactively for non-trivial tasks: new features, multi-file changes, architectural decisions, unclear requirements.
|
|
7
|
+
Skip for: single-line fixes, obvious bugs, specific user instructions.`,
|
|
8
|
+
inputSchema: z.object({}),
|
|
9
|
+
// No execute — handled in agent loop (inject plan mode prompt + wait for user consent)
|
|
10
|
+
});
|
|
11
|
+
//# sourceMappingURL=enter-plan-mode.js.map
|