@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.
Files changed (125) hide show
  1. package/dist/agent/loop.d.ts +19 -0
  2. package/dist/agent/loop.d.ts.map +1 -0
  3. package/dist/agent/loop.js +443 -0
  4. package/dist/agent/loop.js.map +1 -0
  5. package/dist/agent/messages.d.ts +8 -0
  6. package/dist/agent/messages.d.ts.map +1 -0
  7. package/dist/agent/messages.js +51 -0
  8. package/dist/agent/messages.js.map +1 -0
  9. package/dist/agent/plan-mode.d.ts +11 -0
  10. package/dist/agent/plan-mode.d.ts.map +1 -0
  11. package/dist/agent/plan-mode.js +37 -0
  12. package/dist/agent/plan-mode.js.map +1 -0
  13. package/dist/agent/pricing.d.ts +9 -0
  14. package/dist/agent/pricing.d.ts.map +1 -0
  15. package/dist/agent/pricing.js +47 -0
  16. package/dist/agent/pricing.js.map +1 -0
  17. package/dist/agent/system-prompt.d.ts +9 -0
  18. package/dist/agent/system-prompt.d.ts.map +1 -0
  19. package/dist/agent/system-prompt.js +93 -0
  20. package/dist/agent/system-prompt.js.map +1 -0
  21. package/dist/config/index.d.ts +28 -0
  22. package/dist/config/index.d.ts.map +1 -0
  23. package/dist/config/index.js +88 -0
  24. package/dist/config/index.js.map +1 -0
  25. package/dist/index.d.ts +20 -0
  26. package/dist/index.d.ts.map +1 -0
  27. package/dist/index.js +24 -0
  28. package/dist/index.js.map +1 -0
  29. package/dist/knowledge/auto-memory.d.ts +36 -0
  30. package/dist/knowledge/auto-memory.d.ts.map +1 -0
  31. package/dist/knowledge/auto-memory.js +151 -0
  32. package/dist/knowledge/auto-memory.js.map +1 -0
  33. package/dist/knowledge/hooks.d.ts +3 -0
  34. package/dist/knowledge/hooks.d.ts.map +1 -0
  35. package/dist/knowledge/hooks.js +59 -0
  36. package/dist/knowledge/hooks.js.map +1 -0
  37. package/dist/knowledge/init.d.ts +8 -0
  38. package/dist/knowledge/init.d.ts.map +1 -0
  39. package/dist/knowledge/init.js +98 -0
  40. package/dist/knowledge/init.js.map +1 -0
  41. package/dist/knowledge/loader.d.ts +14 -0
  42. package/dist/knowledge/loader.d.ts.map +1 -0
  43. package/dist/knowledge/loader.js +130 -0
  44. package/dist/knowledge/loader.js.map +1 -0
  45. package/dist/knowledge/session.d.ts +11 -0
  46. package/dist/knowledge/session.d.ts.map +1 -0
  47. package/dist/knowledge/session.js +108 -0
  48. package/dist/knowledge/session.js.map +1 -0
  49. package/dist/permissions/index.d.ts +14 -0
  50. package/dist/permissions/index.d.ts.map +1 -0
  51. package/dist/permissions/index.js +46 -0
  52. package/dist/permissions/index.js.map +1 -0
  53. package/dist/providers/registry.d.ts +2 -0
  54. package/dist/providers/registry.d.ts.map +1 -0
  55. package/dist/providers/registry.js +46 -0
  56. package/dist/providers/registry.js.map +1 -0
  57. package/dist/tools/ask-user.d.ts +8 -0
  58. package/dist/tools/ask-user.d.ts.map +1 -0
  59. package/dist/tools/ask-user.js +19 -0
  60. package/dist/tools/ask-user.js.map +1 -0
  61. package/dist/tools/edit.d.ts +7 -0
  62. package/dist/tools/edit.d.ts.map +1 -0
  63. package/dist/tools/edit.js +14 -0
  64. package/dist/tools/edit.js.map +1 -0
  65. package/dist/tools/enter-plan-mode.d.ts +2 -0
  66. package/dist/tools/enter-plan-mode.d.ts.map +1 -0
  67. package/dist/tools/enter-plan-mode.js +11 -0
  68. package/dist/tools/enter-plan-mode.js.map +1 -0
  69. package/dist/tools/exit-plan-mode.d.ts +2 -0
  70. package/dist/tools/exit-plan-mode.d.ts.map +1 -0
  71. package/dist/tools/exit-plan-mode.js +9 -0
  72. package/dist/tools/exit-plan-mode.js.map +1 -0
  73. package/dist/tools/glob.d.ts +5 -0
  74. package/dist/tools/glob.d.ts.map +1 -0
  75. package/dist/tools/glob.js +28 -0
  76. package/dist/tools/glob.js.map +1 -0
  77. package/dist/tools/grep.d.ts +7 -0
  78. package/dist/tools/grep.d.ts.map +1 -0
  79. package/dist/tools/grep.js +54 -0
  80. package/dist/tools/grep.js.map +1 -0
  81. package/dist/tools/index.d.ts +77 -0
  82. package/dist/tools/index.d.ts.map +1 -0
  83. package/dist/tools/index.js +41 -0
  84. package/dist/tools/index.js.map +1 -0
  85. package/dist/tools/list-dir.d.ts +4 -0
  86. package/dist/tools/list-dir.d.ts.map +1 -0
  87. package/dist/tools/list-dir.js +25 -0
  88. package/dist/tools/list-dir.js.map +1 -0
  89. package/dist/tools/read-file.d.ts +6 -0
  90. package/dist/tools/read-file.d.ts.map +1 -0
  91. package/dist/tools/read-file.js +28 -0
  92. package/dist/tools/read-file.js.map +1 -0
  93. package/dist/tools/save-knowledge.d.ts +8 -0
  94. package/dist/tools/save-knowledge.d.ts.map +1 -0
  95. package/dist/tools/save-knowledge.js +36 -0
  96. package/dist/tools/save-knowledge.js.map +1 -0
  97. package/dist/tools/shell-utils.d.ts +14 -0
  98. package/dist/tools/shell-utils.d.ts.map +1 -0
  99. package/dist/tools/shell-utils.js +111 -0
  100. package/dist/tools/shell-utils.js.map +1 -0
  101. package/dist/tools/shell.d.ts +5 -0
  102. package/dist/tools/shell.d.ts.map +1 -0
  103. package/dist/tools/shell.js +12 -0
  104. package/dist/tools/shell.js.map +1 -0
  105. package/dist/tools/web-fetch.d.ts +5 -0
  106. package/dist/tools/web-fetch.d.ts.map +1 -0
  107. package/dist/tools/web-fetch.js +59 -0
  108. package/dist/tools/web-fetch.js.map +1 -0
  109. package/dist/tools/web-search.d.ts +5 -0
  110. package/dist/tools/web-search.d.ts.map +1 -0
  111. package/dist/tools/web-search.js +27 -0
  112. package/dist/tools/web-search.js.map +1 -0
  113. package/dist/tools/write-file.d.ts +5 -0
  114. package/dist/tools/write-file.d.ts.map +1 -0
  115. package/dist/tools/write-file.js +12 -0
  116. package/dist/tools/write-file.js.map +1 -0
  117. package/dist/types/index.d.ts +108 -0
  118. package/dist/types/index.d.ts.map +1 -0
  119. package/dist/types/index.js +36 -0
  120. package/dist/types/index.js.map +1 -0
  121. package/dist/utils.d.ts +9 -0
  122. package/dist/utils.d.ts.map +1 -0
  123. package/dist/utils.js +34 -0
  124. package/dist/utils.js.map +1 -0
  125. 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":"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"}
@@ -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,2 @@
1
+ export declare function createModelRegistry(): import("ai").ProviderRegistryProvider<Record<string, any>, ":">;
2
+ //# sourceMappingURL=registry.d.ts.map
@@ -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,8 @@
1
+ export declare const askUser: import("ai").Tool<{
2
+ options: {
3
+ description: string;
4
+ label: string;
5
+ }[];
6
+ question: string;
7
+ }, never>;
8
+ //# sourceMappingURL=ask-user.d.ts.map
@@ -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,7 @@
1
+ export declare const edit: import("ai").Tool<{
2
+ filePath: string;
3
+ oldString: string;
4
+ newString: string;
5
+ replaceAll?: boolean | undefined;
6
+ }, never>;
7
+ //# sourceMappingURL=edit.d.ts.map
@@ -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,2 @@
1
+ export declare const enterPlanMode: import("ai").Tool<{}, never>;
2
+ //# sourceMappingURL=enter-plan-mode.d.ts.map
@@ -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