@nanocollective/nanocoder 1.16.1 → 1.16.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (112) hide show
  1. package/dist/commands/update.d.ts.map +1 -1
  2. package/dist/commands/update.js +35 -3
  3. package/dist/commands/update.js.map +1 -1
  4. package/dist/components/assistant-message.d.ts +1 -4
  5. package/dist/components/assistant-message.d.ts.map +1 -1
  6. package/dist/components/assistant-message.js +1 -199
  7. package/dist/components/assistant-message.js.map +1 -1
  8. package/dist/config/index.d.ts.map +1 -1
  9. package/dist/config/index.js +13 -5
  10. package/dist/config/index.js.map +1 -1
  11. package/dist/config/paths.d.ts.map +1 -1
  12. package/dist/config/paths.js +23 -2
  13. package/dist/config/paths.js.map +1 -1
  14. package/dist/hooks/useAppState.d.ts.map +1 -1
  15. package/dist/hooks/useAppState.js +8 -15
  16. package/dist/hooks/useAppState.js.map +1 -1
  17. package/dist/hooks/useChatHandler.d.ts.map +1 -1
  18. package/dist/hooks/useChatHandler.js +26 -0
  19. package/dist/hooks/useChatHandler.js.map +1 -1
  20. package/dist/hooks/useTerminalWidth.d.ts.map +1 -1
  21. package/dist/hooks/useTerminalWidth.js +6 -0
  22. package/dist/hooks/useTerminalWidth.js.map +1 -1
  23. package/dist/markdown-parser/html-entities.d.ts +2 -0
  24. package/dist/markdown-parser/html-entities.d.ts.map +1 -0
  25. package/dist/markdown-parser/html-entities.js +41 -0
  26. package/dist/markdown-parser/html-entities.js.map +1 -0
  27. package/dist/markdown-parser/html-entities.spec.d.ts +2 -0
  28. package/dist/markdown-parser/html-entities.spec.d.ts.map +1 -0
  29. package/dist/markdown-parser/html-entities.spec.js +73 -0
  30. package/dist/markdown-parser/html-entities.spec.js.map +1 -0
  31. package/dist/markdown-parser/index.d.ts +6 -0
  32. package/dist/markdown-parser/index.d.ts.map +1 -0
  33. package/dist/markdown-parser/index.js +97 -0
  34. package/dist/markdown-parser/index.js.map +1 -0
  35. package/dist/markdown-parser/index.spec.d.ts +2 -0
  36. package/dist/markdown-parser/index.spec.d.ts.map +1 -0
  37. package/dist/markdown-parser/index.spec.js +245 -0
  38. package/dist/markdown-parser/index.spec.js.map +1 -0
  39. package/dist/markdown-parser/table-parser.d.ts +3 -0
  40. package/dist/markdown-parser/table-parser.d.ts.map +1 -0
  41. package/dist/markdown-parser/table-parser.js +92 -0
  42. package/dist/markdown-parser/table-parser.js.map +1 -0
  43. package/dist/markdown-parser/table-parser.spec.d.ts +2 -0
  44. package/dist/markdown-parser/table-parser.spec.d.ts.map +1 -0
  45. package/dist/markdown-parser/table-parser.spec.js +120 -0
  46. package/dist/markdown-parser/table-parser.spec.js.map +1 -0
  47. package/dist/markdown-parser/utils.d.ts +2 -0
  48. package/dist/markdown-parser/utils.d.ts.map +1 -0
  49. package/dist/markdown-parser/utils.js +14 -0
  50. package/dist/markdown-parser/utils.js.map +1 -0
  51. package/dist/markdown-parser/utils.spec.d.ts +2 -0
  52. package/dist/markdown-parser/utils.spec.d.ts.map +1 -0
  53. package/dist/markdown-parser/utils.spec.js +59 -0
  54. package/dist/markdown-parser/utils.spec.js.map +1 -0
  55. package/dist/models/models-dev-client.d.ts.map +1 -1
  56. package/dist/models/models-dev-client.js +7 -1
  57. package/dist/models/models-dev-client.js.map +1 -1
  58. package/dist/models/models-dev-client.spec.d.ts +2 -0
  59. package/dist/models/models-dev-client.spec.d.ts.map +1 -0
  60. package/dist/models/models-dev-client.spec.js +302 -0
  61. package/dist/models/models-dev-client.spec.js.map +1 -0
  62. package/dist/tool-calling/xml-parser.d.ts.map +1 -1
  63. package/dist/tool-calling/xml-parser.js +39 -0
  64. package/dist/tool-calling/xml-parser.js.map +1 -1
  65. package/dist/tool-calling/xml-parser.spec.js +43 -0
  66. package/dist/tool-calling/xml-parser.spec.js.map +1 -1
  67. package/dist/tools/execute-bash.d.ts.map +1 -1
  68. package/dist/tools/execute-bash.js +12 -27
  69. package/dist/tools/execute-bash.js.map +1 -1
  70. package/dist/tools/find-files.d.ts +3 -0
  71. package/dist/tools/find-files.d.ts.map +1 -0
  72. package/dist/tools/find-files.js +186 -0
  73. package/dist/tools/find-files.js.map +1 -0
  74. package/dist/tools/index.js +4 -4
  75. package/dist/tools/index.js.map +1 -1
  76. package/dist/tools/read-file.d.ts.map +1 -1
  77. package/dist/tools/read-file.js +143 -9
  78. package/dist/tools/read-file.js.map +1 -1
  79. package/dist/tools/search-file-contents.d.ts +3 -0
  80. package/dist/tools/search-file-contents.d.ts.map +1 -0
  81. package/dist/tools/search-file-contents.js +164 -0
  82. package/dist/tools/search-file-contents.js.map +1 -0
  83. package/dist/types/index.d.ts +0 -1
  84. package/dist/types/index.d.ts.map +1 -1
  85. package/dist/types/index.js +0 -1
  86. package/dist/types/index.js.map +1 -1
  87. package/dist/types/markdown-parser.d.ts +11 -0
  88. package/dist/types/markdown-parser.d.ts.map +1 -0
  89. package/dist/types/markdown-parser.js +2 -0
  90. package/dist/types/markdown-parser.js.map +1 -0
  91. package/dist/utils/update-checker.spec.d.ts +2 -0
  92. package/dist/utils/update-checker.spec.d.ts.map +1 -0
  93. package/dist/utils/update-checker.spec.js +230 -0
  94. package/dist/utils/update-checker.spec.js.map +1 -0
  95. package/package.json +1 -1
  96. package/source/app/prompts/main-prompt.md +67 -23
  97. package/dist/components/update-message.d.ts +0 -7
  98. package/dist/components/update-message.d.ts.map +0 -1
  99. package/dist/components/update-message.js +0 -93
  100. package/dist/components/update-message.js.map +0 -1
  101. package/dist/tools/read-many-files.d.ts +0 -3
  102. package/dist/tools/read-many-files.d.ts.map +0 -1
  103. package/dist/tools/read-many-files.js +0 -169
  104. package/dist/tools/read-many-files.js.map +0 -1
  105. package/dist/tools/search-files.d.ts +0 -3
  106. package/dist/tools/search-files.d.ts.map +0 -1
  107. package/dist/tools/search-files.js +0 -250
  108. package/dist/tools/search-files.js.map +0 -1
  109. package/dist/types/tools.d.ts +0 -5
  110. package/dist/types/tools.d.ts.map +0 -1
  111. package/dist/types/tools.js +0 -2
  112. package/dist/types/tools.js.map +0 -1
@@ -0,0 +1,164 @@
1
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
+ import { exec } from 'node:child_process';
3
+ import { promisify } from 'node:util';
4
+ import { readFileSync, existsSync } from 'node:fs';
5
+ import { join } from 'node:path';
6
+ import React from 'react';
7
+ import ignore from 'ignore';
8
+ import { Text, Box } from 'ink';
9
+ import { tool, jsonSchema } from '../types/core.js';
10
+ import { ThemeContext } from '../hooks/useTheme.js';
11
+ import ToolMessage from '../components/tool-message.js';
12
+ const execAsync = promisify(exec);
13
+ /**
14
+ * Load and parse .gitignore file, returns an ignore instance
15
+ */
16
+ function loadGitignore(cwd) {
17
+ const ig = ignore();
18
+ const gitignorePath = join(cwd, '.gitignore');
19
+ // Always ignore common directories
20
+ ig.add([
21
+ 'node_modules',
22
+ '.git',
23
+ 'dist',
24
+ 'build',
25
+ 'coverage',
26
+ '.next',
27
+ '.nuxt',
28
+ 'out',
29
+ '.cache',
30
+ ]);
31
+ // Load .gitignore if it exists
32
+ if (existsSync(gitignorePath)) {
33
+ try {
34
+ const gitignoreContent = readFileSync(gitignorePath, 'utf-8');
35
+ ig.add(gitignoreContent);
36
+ }
37
+ catch {
38
+ // Silently fail if we can't read .gitignore
39
+ // The hardcoded ignores above will still apply
40
+ }
41
+ }
42
+ return ig;
43
+ }
44
+ /**
45
+ * Search file contents using grep
46
+ */
47
+ async function searchFileContents(query, cwd, maxResults, caseSensitive) {
48
+ try {
49
+ const ig = loadGitignore(cwd);
50
+ // Escape query for shell safety
51
+ const escapedQuery = query.replace(/"/g, '\\"');
52
+ // Use grep with basic exclusions for performance
53
+ const caseFlag = caseSensitive ? '' : '-i';
54
+ const { stdout } = await execAsync(`grep -rn ${caseFlag} --include="*" --exclude-dir={node_modules,.git,dist,build,coverage,.next,.nuxt,out,.cache} "${escapedQuery}" . | head -n ${maxResults * 3}`, { cwd, maxBuffer: 1024 * 1024 });
55
+ const matches = [];
56
+ const lines = stdout.trim().split('\n').filter(Boolean);
57
+ for (const line of lines) {
58
+ const match = line.match(/^\.\/(.+?):(\d+):(.*)$/);
59
+ if (match) {
60
+ const filePath = match[1];
61
+ // Skip files ignored by gitignore
62
+ if (ig.ignores(filePath)) {
63
+ continue;
64
+ }
65
+ matches.push({
66
+ file: filePath,
67
+ line: parseInt(match[2], 10),
68
+ content: match[3].trim(),
69
+ });
70
+ // Stop once we have enough matches
71
+ if (matches.length >= maxResults) {
72
+ break;
73
+ }
74
+ }
75
+ }
76
+ return {
77
+ matches,
78
+ truncated: lines.length >= maxResults * 3 || matches.length >= maxResults,
79
+ };
80
+ }
81
+ catch (error) {
82
+ // grep returns exit code 1 when no matches found
83
+ if (error instanceof Error && 'code' in error && error.code === 1) {
84
+ return { matches: [], truncated: false };
85
+ }
86
+ throw error;
87
+ }
88
+ }
89
+ const executeSearchFileContents = async (args) => {
90
+ const cwd = process.cwd();
91
+ const maxResults = Math.min(args.maxResults || 30, 100);
92
+ const caseSensitive = args.caseSensitive || false;
93
+ try {
94
+ const { matches, truncated } = await searchFileContents(args.query, cwd, maxResults, caseSensitive);
95
+ if (matches.length === 0) {
96
+ return `No matches found for "${args.query}"`;
97
+ }
98
+ // Format results with clear file:line format
99
+ let output = `Found ${matches.length} match${matches.length === 1 ? '' : 'es'}${truncated ? ` (showing first ${maxResults})` : ''}:\n\n`;
100
+ for (const match of matches) {
101
+ output += `${match.file}:${match.line}\n`;
102
+ output += ` ${match.content}\n\n`;
103
+ }
104
+ return output.trim();
105
+ }
106
+ catch (error) {
107
+ const errorMessage = error instanceof Error ? error.message : 'Unknown error';
108
+ throw new Error(`Content search failed: ${errorMessage}`);
109
+ }
110
+ };
111
+ // AI SDK tool definition
112
+ const searchFileContentsCoreTool = tool({
113
+ description: 'Search for text or code INSIDE file contents. Returns file paths with line numbers and matching content. Use this to find where specific code, functions, variables, or text appears in the codebase.',
114
+ inputSchema: jsonSchema({
115
+ type: 'object',
116
+ properties: {
117
+ query: {
118
+ type: 'string',
119
+ description: 'Text or code to search for inside files. Examples: "handleSubmit", "import React", "TODO", "function calculateTotal". Search is case-insensitive by default.',
120
+ },
121
+ maxResults: {
122
+ type: 'number',
123
+ description: 'Maximum number of matches to return (default: 30, max: 100)',
124
+ },
125
+ caseSensitive: {
126
+ type: 'boolean',
127
+ description: 'Whether to perform case-sensitive search (default: false)',
128
+ },
129
+ },
130
+ required: ['query'],
131
+ }),
132
+ });
133
+ const SearchFileContentsFormatter = React.memo(({ args, result }) => {
134
+ const themeContext = React.useContext(ThemeContext);
135
+ if (!themeContext) {
136
+ throw new Error('ThemeContext not found');
137
+ }
138
+ const { colors } = themeContext;
139
+ // Parse result to get match count
140
+ let matchCount = 0;
141
+ if (result && !result.startsWith('Error:')) {
142
+ const firstLine = result.split('\n')[0];
143
+ const matchFound = firstLine.match(/Found (\d+)/);
144
+ if (matchFound) {
145
+ matchCount = parseInt(matchFound[1], 10);
146
+ }
147
+ }
148
+ const messageContent = (_jsxs(Box, { flexDirection: "column", children: [_jsx(Text, { color: colors.tool, children: "\u2692 search_file_contents" }), _jsxs(Box, { children: [_jsx(Text, { color: colors.secondary, children: "Query: " }), _jsx(Text, { color: colors.white, children: args.query })] }), args.caseSensitive && (_jsxs(Box, { children: [_jsx(Text, { color: colors.secondary, children: "Case sensitive: " }), _jsx(Text, { color: colors.white, children: "yes" })] })), _jsxs(Box, { children: [_jsx(Text, { color: colors.secondary, children: "Matches: " }), _jsx(Text, { color: colors.white, children: matchCount })] })] }));
149
+ return _jsx(ToolMessage, { message: messageContent, hideBox: true });
150
+ });
151
+ const formatter = (args, result) => {
152
+ if (result && result.startsWith('Error:')) {
153
+ return _jsx(_Fragment, {});
154
+ }
155
+ return _jsx(SearchFileContentsFormatter, { args: args, result: result });
156
+ };
157
+ export const searchFileContentsTool = {
158
+ name: 'search_file_contents',
159
+ tool: searchFileContentsCoreTool,
160
+ handler: executeSearchFileContents,
161
+ formatter,
162
+ requiresConfirmation: false,
163
+ };
164
+ //# sourceMappingURL=search-file-contents.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"search-file-contents.js","sourceRoot":"","sources":["../../source/tools/search-file-contents.tsx"],"names":[],"mappings":"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"}
@@ -3,7 +3,6 @@ export * from '../types/config.js';
3
3
  export * from '../types/mcp.js';
4
4
  export * from '../types/commands.js';
5
5
  export * from '../types/ui.js';
6
- export * from '../types/tools.js';
7
6
  export * from '../types/app.js';
8
7
  export * from '../types/utils.js';
9
8
  export * from '../types/components.js';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../source/types/index.ts"],"names":[],"mappings":"AACA,cAAc,cAAc,CAAC;AAC7B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,aAAa,CAAC;AAC5B,cAAc,kBAAkB,CAAC;AACjC,cAAc,YAAY,CAAC;AAC3B,cAAc,eAAe,CAAC;AAC9B,cAAc,aAAa,CAAC;AAC5B,cAAc,eAAe,CAAC;AAC9B,cAAc,oBAAoB,CAAC;AACnC,cAAc,eAAe,CAAC;AAC9B,cAAc,gBAAgB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../source/types/index.ts"],"names":[],"mappings":"AACA,cAAc,cAAc,CAAC;AAC7B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,aAAa,CAAC;AAC5B,cAAc,kBAAkB,CAAC;AACjC,cAAc,YAAY,CAAC;AAC3B,cAAc,aAAa,CAAC;AAC5B,cAAc,eAAe,CAAC;AAC9B,cAAc,oBAAoB,CAAC;AACnC,cAAc,eAAe,CAAC;AAC9B,cAAc,gBAAgB,CAAC"}
@@ -4,7 +4,6 @@ export * from '../types/config.js';
4
4
  export * from '../types/mcp.js';
5
5
  export * from '../types/commands.js';
6
6
  export * from '../types/ui.js';
7
- export * from '../types/tools.js';
8
7
  export * from '../types/app.js';
9
8
  export * from '../types/utils.js';
10
9
  export * from '../types/components.js';
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../source/types/index.ts"],"names":[],"mappings":"AAAA,6CAA6C;AAC7C,cAAc,cAAc,CAAC;AAC7B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,aAAa,CAAC;AAC5B,cAAc,kBAAkB,CAAC;AACjC,cAAc,YAAY,CAAC;AAC3B,cAAc,eAAe,CAAC;AAC9B,cAAc,aAAa,CAAC;AAC5B,cAAc,eAAe,CAAC;AAC9B,cAAc,oBAAoB,CAAC;AACnC,cAAc,eAAe,CAAC;AAC9B,cAAc,gBAAgB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../source/types/index.ts"],"names":[],"mappings":"AAAA,6CAA6C;AAC7C,cAAc,cAAc,CAAC;AAC7B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,aAAa,CAAC;AAC5B,cAAc,kBAAkB,CAAC;AACjC,cAAc,YAAY,CAAC;AAC3B,cAAc,aAAa,CAAC;AAC5B,cAAc,eAAe,CAAC;AAC9B,cAAc,oBAAoB,CAAC;AACnC,cAAc,eAAe,CAAC;AAC9B,cAAc,gBAAgB,CAAC"}
@@ -0,0 +1,11 @@
1
+ export interface Colors {
2
+ primary: string;
3
+ secondary: string;
4
+ success: string;
5
+ error: string;
6
+ warning: string;
7
+ info: string;
8
+ white: string;
9
+ tool: string;
10
+ }
11
+ //# sourceMappingURL=markdown-parser.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"markdown-parser.d.ts","sourceRoot":"","sources":["../../source/types/markdown-parser.ts"],"names":[],"mappings":"AACA,MAAM,WAAW,MAAM;IACtB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;CACb"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=markdown-parser.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"markdown-parser.js","sourceRoot":"","sources":["../../source/types/markdown-parser.ts"],"names":[],"mappings":""}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=update-checker.spec.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"update-checker.spec.d.ts","sourceRoot":"","sources":["../../source/utils/update-checker.spec.ts"],"names":[],"mappings":""}
@@ -0,0 +1,230 @@
1
+ import test from 'ava';
2
+ import { checkForUpdates } from './update-checker.js';
3
+ console.log(`\nupdate-checker.spec.ts`);
4
+ // Mock fetch globally for testing
5
+ const originalFetch = globalThis.fetch;
6
+ // Helper to create mock fetch responses
7
+ function createMockFetch(status, data, shouldReject = false) {
8
+ return (async () => {
9
+ if (shouldReject) {
10
+ throw new Error('Network error');
11
+ }
12
+ return {
13
+ ok: status >= 200 && status < 300,
14
+ status,
15
+ statusText: status === 200 ? 'OK' : 'Error',
16
+ json: async () => data,
17
+ };
18
+ });
19
+ }
20
+ test.beforeEach(() => {
21
+ // Reset fetch before each test
22
+ globalThis.fetch = originalFetch;
23
+ });
24
+ test.afterEach(() => {
25
+ // Restore original fetch after each test
26
+ globalThis.fetch = originalFetch;
27
+ });
28
+ // Version Comparison Tests
29
+ test('checkForUpdates: detects newer major version', async (t) => {
30
+ globalThis.fetch = createMockFetch(200, {
31
+ version: '2.0.0',
32
+ name: '@nanocollective/nanocoder',
33
+ });
34
+ const result = await checkForUpdates();
35
+ t.true(result.hasUpdate);
36
+ t.is(result.currentVersion, '1.16.3');
37
+ t.is(result.latestVersion, '2.0.0');
38
+ t.truthy(result.updateCommand);
39
+ });
40
+ test('checkForUpdates: detects newer minor version', async (t) => {
41
+ globalThis.fetch = createMockFetch(200, {
42
+ version: '1.17.0',
43
+ name: '@nanocollective/nanocoder',
44
+ });
45
+ const result = await checkForUpdates();
46
+ t.true(result.hasUpdate);
47
+ t.is(result.latestVersion, '1.17.0');
48
+ });
49
+ test('checkForUpdates: detects newer patch version', async (t) => {
50
+ globalThis.fetch = createMockFetch(200, {
51
+ version: '1.16.4',
52
+ name: '@nanocollective/nanocoder',
53
+ });
54
+ const result = await checkForUpdates();
55
+ t.true(result.hasUpdate);
56
+ t.is(result.latestVersion, '1.16.4');
57
+ });
58
+ test('checkForUpdates: detects same version (no update)', async (t) => {
59
+ globalThis.fetch = createMockFetch(200, {
60
+ version: '1.16.3',
61
+ name: '@nanocollective/nanocoder',
62
+ });
63
+ const result = await checkForUpdates();
64
+ t.false(result.hasUpdate);
65
+ t.is(result.currentVersion, '1.16.3');
66
+ t.is(result.latestVersion, '1.16.3');
67
+ t.is(result.updateCommand, undefined);
68
+ });
69
+ test('checkForUpdates: detects older version (no update)', async (t) => {
70
+ globalThis.fetch = createMockFetch(200, {
71
+ version: '1.16.2',
72
+ name: '@nanocollective/nanocoder',
73
+ });
74
+ const result = await checkForUpdates();
75
+ t.false(result.hasUpdate);
76
+ t.is(result.latestVersion, '1.16.2');
77
+ });
78
+ test('checkForUpdates: handles version with v prefix', async (t) => {
79
+ globalThis.fetch = createMockFetch(200, {
80
+ version: 'v2.0.0',
81
+ name: '@nanocollective/nanocoder',
82
+ });
83
+ const result = await checkForUpdates();
84
+ t.true(result.hasUpdate);
85
+ t.is(result.latestVersion, 'v2.0.0');
86
+ });
87
+ test('checkForUpdates: handles pre-release versions', async (t) => {
88
+ globalThis.fetch = createMockFetch(200, {
89
+ version: '2.0.0-beta.1',
90
+ name: '@nanocollective/nanocoder',
91
+ });
92
+ const result = await checkForUpdates();
93
+ // Pre-release info is stripped, so 2.0.0 > 1.16.3
94
+ t.true(result.hasUpdate);
95
+ t.is(result.latestVersion, '2.0.0-beta.1');
96
+ });
97
+ // Network Error Handling Tests
98
+ test('checkForUpdates: handles network errors gracefully', async (t) => {
99
+ globalThis.fetch = createMockFetch(200, {}, true);
100
+ const result = await checkForUpdates();
101
+ t.false(result.hasUpdate);
102
+ t.truthy(result.currentVersion);
103
+ t.is(result.latestVersion, undefined);
104
+ });
105
+ test('checkForUpdates: handles HTTP 404 error', async (t) => {
106
+ globalThis.fetch = createMockFetch(404, {
107
+ error: 'Not found',
108
+ });
109
+ const result = await checkForUpdates();
110
+ t.false(result.hasUpdate);
111
+ t.truthy(result.currentVersion);
112
+ });
113
+ test('checkForUpdates: handles HTTP 500 error', async (t) => {
114
+ globalThis.fetch = createMockFetch(500, {
115
+ error: 'Internal server error',
116
+ });
117
+ const result = await checkForUpdates();
118
+ t.false(result.hasUpdate);
119
+ t.truthy(result.currentVersion);
120
+ });
121
+ test('checkForUpdates: handles timeout (via AbortSignal)', async (t) => {
122
+ // Simulate timeout by throwing AbortError
123
+ globalThis.fetch = (async () => {
124
+ const error = new Error('The operation was aborted');
125
+ error.name = 'AbortError';
126
+ throw error;
127
+ });
128
+ const result = await checkForUpdates();
129
+ // Should handle timeout gracefully
130
+ t.false(result.hasUpdate);
131
+ });
132
+ // Response Format Tests
133
+ test('checkForUpdates: returns correct update command', async (t) => {
134
+ globalThis.fetch = createMockFetch(200, {
135
+ version: '2.0.0',
136
+ name: '@nanocollective/nanocoder',
137
+ });
138
+ const result = await checkForUpdates();
139
+ t.is(result.updateCommand, 'npm update -g @nanocollective/nanocoder');
140
+ });
141
+ test('checkForUpdates: includes current version in response', async (t) => {
142
+ globalThis.fetch = createMockFetch(200, {
143
+ version: '2.0.0',
144
+ name: '@nanocollective/nanocoder',
145
+ });
146
+ const result = await checkForUpdates();
147
+ t.truthy(result.currentVersion);
148
+ t.regex(result.currentVersion, /^\d+\.\d+\.\d+/);
149
+ });
150
+ test('checkForUpdates: handles missing version field in response', async (t) => {
151
+ globalThis.fetch = createMockFetch(200, {
152
+ name: '@nanocollective/nanocoder',
153
+ // version field missing
154
+ });
155
+ const result = await checkForUpdates();
156
+ t.false(result.hasUpdate);
157
+ });
158
+ test('checkForUpdates: handles malformed JSON response', async (t) => {
159
+ globalThis.fetch = (async () => {
160
+ return {
161
+ ok: true,
162
+ status: 200,
163
+ statusText: 'OK',
164
+ json: async () => {
165
+ throw new Error('Invalid JSON');
166
+ },
167
+ };
168
+ });
169
+ const result = await checkForUpdates();
170
+ t.false(result.hasUpdate);
171
+ });
172
+ // Edge Cases
173
+ test('checkForUpdates: handles empty version string', async (t) => {
174
+ globalThis.fetch = createMockFetch(200, {
175
+ version: '',
176
+ name: '@nanocollective/nanocoder',
177
+ });
178
+ const result = await checkForUpdates();
179
+ t.false(result.hasUpdate);
180
+ });
181
+ test('checkForUpdates: handles version with extra segments', async (t) => {
182
+ globalThis.fetch = createMockFetch(200, {
183
+ version: '2.0.0.1',
184
+ name: '@nanocollective/nanocoder',
185
+ });
186
+ const result = await checkForUpdates();
187
+ // Should compare first 3 segments
188
+ t.true(result.hasUpdate);
189
+ });
190
+ test('checkForUpdates: handles invalid version format', async (t) => {
191
+ globalThis.fetch = createMockFetch(200, {
192
+ version: 'not-a-version',
193
+ name: '@nanocollective/nanocoder',
194
+ });
195
+ const result = await checkForUpdates();
196
+ // Should handle gracefully
197
+ t.false(result.hasUpdate);
198
+ });
199
+ // Integration Tests
200
+ test('checkForUpdates: complete workflow for update available', async (t) => {
201
+ globalThis.fetch = createMockFetch(200, {
202
+ version: '99.99.99',
203
+ name: '@nanocollective/nanocoder',
204
+ });
205
+ const result = await checkForUpdates();
206
+ t.true(result.hasUpdate);
207
+ t.truthy(result.currentVersion);
208
+ t.is(result.latestVersion, '99.99.99');
209
+ t.is(result.updateCommand, 'npm update -g @nanocollective/nanocoder');
210
+ });
211
+ test('checkForUpdates: complete workflow for no update', async (t) => {
212
+ globalThis.fetch = createMockFetch(200, {
213
+ version: '0.0.1',
214
+ name: '@nanocollective/nanocoder',
215
+ });
216
+ const result = await checkForUpdates();
217
+ t.false(result.hasUpdate);
218
+ t.truthy(result.currentVersion);
219
+ t.is(result.latestVersion, '0.0.1');
220
+ t.is(result.updateCommand, undefined);
221
+ });
222
+ test('checkForUpdates: complete workflow for network failure', async (t) => {
223
+ globalThis.fetch = createMockFetch(200, {}, true);
224
+ const result = await checkForUpdates();
225
+ t.false(result.hasUpdate);
226
+ t.truthy(result.currentVersion);
227
+ t.is(result.latestVersion, undefined);
228
+ t.is(result.updateCommand, undefined);
229
+ });
230
+ //# sourceMappingURL=update-checker.spec.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"update-checker.spec.js","sourceRoot":"","sources":["../../source/utils/update-checker.spec.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@nanocollective/nanocoder",
3
3
  "main": "dist/cli.js",
4
- "version": "1.16.1",
4
+ "version": "1.16.3",
5
5
  "description": "A local-first CLI coding agent that brings the power of agentic coding tools like Claude Code and Gemini CLI to local models or controlled APIs like OpenRouter",
6
6
  "keywords": [
7
7
  "cli",
@@ -128,9 +128,9 @@ You have access to powerful tools for understanding codebases and gathering cont
128
128
 
129
129
  ## Code Exploration Strategy
130
130
 
131
- - **search_files**: Perform regex searches across files to find patterns, implementations, or areas needing refactoring
132
- - **read_file**: Examine the full contents of specific files with line numbers for precise editing
133
- - **read_many_files**: Read multiple files at once for efficiency
131
+ - **read_file**: Read files with progressive disclosure (metadata first for files >300 lines, then content with line ranges)
132
+ - **search_file_contents**: Search for text or code inside files to find patterns, implementations, or areas needing refactoring
133
+ - **find_files**: Find files by path pattern or name using glob patterns
134
134
  - **execute_bash**: Run bash commands that can help you find and search for information in the codebase
135
135
 
136
136
  ## Efficient Context Gathering
@@ -138,11 +138,13 @@ You have access to powerful tools for understanding codebases and gathering cont
138
138
  Use these tools in combination for comprehensive analysis:
139
139
 
140
140
  1. Analyze file structure to understand project organization
141
- 2. Use search_files to find specific patterns or implementations
142
- 3. Use read_file or read_many_files to examine contents with line numbers
143
- 4. Make informed changes based on comprehensive understanding
141
+ 2. Use find_files to locate relevant files by pattern (e.g., all TypeScript files, all components)
142
+ 3. Use search_file_contents to find specific code patterns or text across the codebase
143
+ 4. Use read_file to check files (automatically returns metadata for large files)
144
+ 5. Use read_file with line ranges to examine specific code sections
145
+ 6. Make informed changes based on comprehensive understanding
144
146
 
145
- **Example workflow**: When asked to make edits or improvements, you might use search_files to find relevant code patterns, read_file to examine contents with line numbers, analyze and suggest improvements, then use the appropriate editing tool (insert_lines, replace_lines, or delete_lines) with the line numbers from read_file. If refactoring affects other parts of the codebase, use search_files to ensure all necessary updates are made.
147
+ **Example workflow**: When asked to make edits or improvements, you might use find_files to locate relevant files, use search_file_contents to find where specific code is used, use read_file to check the target file (gets metadata if large), read_file with line ranges to examine contents, analyze and suggest improvements, then use the appropriate editing tool (insert_lines, replace_lines, or delete_lines) with the line numbers from read_file. If refactoring affects other parts of the codebase, use search_file_contents to ensure all necessary updates are made.
146
148
 
147
149
  ====
148
150
 
@@ -152,7 +154,22 @@ You have access to different tools for working with files. Understanding their r
152
154
 
153
155
  ## read_file
154
156
 
155
- **Purpose**: Read the contents of a file at the specified path with line numbers.
157
+ **Purpose**: Read file contents with line numbers. Uses PROGRESSIVE DISCLOSURE to prevent context overload.
158
+
159
+ **Parameters**:
160
+
161
+ - `path` (required): The file path to read
162
+ - `start_line` (optional): Line number to start reading from (1-indexed)
163
+ - `end_line` (optional): Line number to stop reading at (inclusive)
164
+
165
+ **How It Works (Progressive Disclosure)**:
166
+
167
+ 1. **First call without line ranges**: Returns metadata only (file size, lines, tokens, type)
168
+
169
+ - Files ≤300 lines: Returns full content immediately
170
+ - Files >300 lines: Returns metadata + instructions to call again with line ranges
171
+
172
+ 2. **Second call with line ranges**: Returns actual file content for the specified range
156
173
 
157
174
  **When to Use**:
158
175
 
@@ -167,15 +184,34 @@ You have access to different tools for working with files. Understanding their r
167
184
  - Returns content with line numbers in format ` 1: line content` for precise editing
168
185
  - If the user provides file contents in their message, you don't need to read again
169
186
 
170
- ## read_many_files
187
+ **Example Workflows**:
171
188
 
172
- **Purpose**: Read multiple files at once efficiently.
189
+ **Small files (<300 lines)**:
173
190
 
174
- **When to Use**:
191
+ - `read_file({path: "config.json"})` → Returns full content immediately
192
+
193
+ **Medium files (300-500 lines)**:
175
194
 
176
- - When you need to examine several related files
177
- - To understand context across multiple files before making changes
178
- - More efficient than multiple read_file calls
195
+ - `read_file({path: "components.tsx"})` Returns metadata
196
+ - Read progressively in chunks:
197
+ - `read_file({path: "components.tsx", start_line: 1, end_line: 250})`
198
+ - `read_file({path: "components.tsx", start_line: 251, end_line: 411})`
199
+
200
+ **Large files (>500 lines) - Two approaches**:
201
+
202
+ **Approach 1: Targeted read** (when you know what you need)
203
+
204
+ 1. `read_file({path: "src/app.tsx"})` → Returns: "1543 lines, ~12k tokens"
205
+ 2. `search_file_contents({query: "handleSubmit"})` → Returns: "Found at app.tsx:458"
206
+ 3. `read_file({path: "src/app.tsx", start_line: 450, end_line: 550})` → Returns content
207
+
208
+ **Approach 2: Progressive read** (when you need to understand the whole file)
209
+
210
+ 1. `read_file({path: "README.md"})` → Returns metadata with suggested chunks
211
+ 2. Read each chunk sequentially (the metadata response provides exact line ranges)
212
+ 3. Process all chunks to understand complete file
213
+
214
+ **IMPORTANT**: When summarizing or analyzing entire files, use progressive reading. Don't skip to the end - read all chunks sequentially.
179
215
 
180
216
  ## create_file
181
217
 
@@ -364,7 +400,7 @@ Coding is one of the most important use cases for you as Nanocoder. Follow these
364
400
 
365
401
  - When modifying code with upstream and downstream dependencies, update them
366
402
  - If you don't know if code has dependencies, use tools to figure it out
367
- - Use search_files to find all references to modified code
403
+ - Use search_file_contents to find all references to modified code
368
404
  - Ensure changes are compatible with the existing codebase
369
405
 
370
406
  ## Code Style and Patterns
@@ -410,10 +446,10 @@ Follow this systematic approach for all tasks:
410
446
  ## 2. Gather Context
411
447
 
412
448
  - Use file structure information if available
413
- - Explore relevant directories with list_files
414
- - Search for patterns with search_files
449
+ - Find relevant files with find_files using glob patterns
450
+ - Search for code patterns with search_file_contents
415
451
  - Read relevant files to understand current state
416
- - Use list_code_definition_names for code overview
452
+ - Use code search tools to understand how code is used across the project
417
453
 
418
454
  ## 3. Execute Step-by-Step
419
455
 
@@ -542,8 +578,7 @@ Here's a comprehensive overview of all available tools and when to use them:
542
578
 
543
579
  ## File Reading
544
580
 
545
- - **read_file**: Read a single file with line numbers for precise editing
546
- - **read_many_files**: Read multiple files at once for efficiency
581
+ - **read_file**: Read files with progressive disclosure. Files >300 lines return metadata first, then call again with start_line/end_line to read content
547
582
 
548
583
  ## File Creation
549
584
 
@@ -557,9 +592,18 @@ Here's a comprehensive overview of all available tools and when to use them:
557
592
 
558
593
  ## File & Code Search
559
594
 
560
- - **search_files**: Search file contents by query OR find files by glob pattern
561
- - Content search: `{query: "searchTerm"}` - finds text in files with context
562
- - File search: `{pattern: "**/*.ts"}` - finds files matching glob pattern
595
+ - **search_file_contents**: Search for text or code INSIDE file contents
596
+
597
+ - Use this to find where specific code, functions, variables, or text appears in the codebase
598
+ - Example: `{query: "handleSubmit"}` - finds files containing "handleSubmit" and shows file:line matches with content
599
+ - Returns file paths with line numbers and matching content
600
+ - Case-insensitive by default, can be made case-sensitive with `caseSensitive: true`
601
+
602
+ - **find_files**: Find files and directories by path pattern or name
603
+ - Use glob patterns to find files and directories by their path or name (not content)
604
+ - Examples: `{pattern: "*.tsx"}` finds all .tsx files, `{pattern: "src/**/*.ts"}` finds all .ts files in src/, `{pattern: "components/**"}` finds all files and directories in components/
605
+ - Returns list of matching file and directory paths
606
+ - Supports brace expansion: `{pattern: "*.{ts,tsx}"}`
563
607
 
564
608
  ## Terminal
565
609