@hasna/terminal 1.6.0 → 1.6.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/dist/ai.js +13 -2
  2. package/package.json +1 -1
  3. package/src/ai.ts +18 -3
package/dist/ai.js CHANGED
@@ -119,10 +119,19 @@ function detectProjectContext() {
119
119
  // Top-level dirs
120
120
  const topLevel = execSync("ls -1", { cwd, encoding: "utf8", timeout: 2000 }).trim();
121
121
  parts.push(`Top-level: ${topLevel.split("\n").join(", ")}`);
122
+ // Detect monorepo (packages/ or workspaces in package.json)
123
+ const isMonorepo = existsSync(join(cwd, "packages")) || existsSync(join(cwd, "apps"));
124
+ if (isMonorepo) {
125
+ const pkgDirs = execSync(`ls -d packages/*/src 2>/dev/null || ls -d apps/*/src 2>/dev/null || echo ""`, { cwd, encoding: "utf8", timeout: 2000 }).trim();
126
+ if (pkgDirs) {
127
+ parts.push(`MONOREPO: Source is in packages/*/src/, NOT src/. Search packages/ not src/.`);
128
+ parts.push(`Package sources:\n${pkgDirs}`);
129
+ }
130
+ }
122
131
  // src/ structure — include FILES so AI knows exact filenames + extensions
123
- for (const srcDir of ["src", "lib", "app"]) {
132
+ for (const srcDir of isMonorepo ? ["packages"] : ["src", "lib", "app"]) {
124
133
  if (existsSync(join(cwd, srcDir))) {
125
- const tree = execSync(`find ${srcDir} -maxdepth 3 -not -path '*/node_modules/*' -not -path '*/dist/*' -not -name '*.test.*' -not -name '*.spec.*' 2>/dev/null | sort | head -60`, { cwd, encoding: "utf8", timeout: 2000 }).trim();
134
+ const tree = execSync(`find ${srcDir} -maxdepth ${isMonorepo ? 4 : 3} -not -path '*/node_modules/*' -not -path '*/dist/*' -not -name '*.test.*' -not -name '*.spec.*' 2>/dev/null | sort | head -80`, { cwd, encoding: "utf8", timeout: 3000 }).trim();
126
135
  if (tree)
127
136
  parts.push(`Files in ${srcDir}/:\n${tree}`);
128
137
  break;
@@ -203,6 +212,8 @@ SEMANTIC MAPPING: When the user references a concept, search the file tree for R
203
212
  - When uncertain: grep -rn "keyword" src/ --include="*.ts" -l (list matching files)
204
213
 
205
214
  ACTION vs CONCEPTUAL: If the prompt starts with "run", "execute", "check", "test", "build", "show output of" — ALWAYS generate an executable command. NEVER read README for action requests. Only read docs for "explain why", "what does X mean", "how was X designed".
215
+
216
+ MONOREPO: If the project context says "MONOREPO", search packages/ or apps/ NOT src/. Use: grep -rn "pattern" packages/ --include="*.ts". For specific packages, use packages/PKGNAME/src/.
206
217
  cwd: ${process.cwd()}
207
218
  shell: zsh / macOS${projectContext}${restrictionBlock}${contextBlock}`;
208
219
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hasna/terminal",
3
- "version": "1.6.0",
3
+ "version": "1.6.1",
4
4
  "description": "Smart terminal wrapper for AI agents and humans — structured output, token compression, MCP server, natural language",
5
5
  "type": "module",
6
6
  "bin": {
package/src/ai.ts CHANGED
@@ -148,12 +148,25 @@ function detectProjectContext(): string {
148
148
  const topLevel = execSync("ls -1", { cwd, encoding: "utf8", timeout: 2000 }).trim();
149
149
  parts.push(`Top-level: ${topLevel.split("\n").join(", ")}`);
150
150
 
151
+ // Detect monorepo (packages/ or workspaces in package.json)
152
+ const isMonorepo = existsSync(join(cwd, "packages")) || existsSync(join(cwd, "apps"));
153
+ if (isMonorepo) {
154
+ const pkgDirs = execSync(
155
+ `ls -d packages/*/src 2>/dev/null || ls -d apps/*/src 2>/dev/null || echo ""`,
156
+ { cwd, encoding: "utf8", timeout: 2000 }
157
+ ).trim();
158
+ if (pkgDirs) {
159
+ parts.push(`MONOREPO: Source is in packages/*/src/, NOT src/. Search packages/ not src/.`);
160
+ parts.push(`Package sources:\n${pkgDirs}`);
161
+ }
162
+ }
163
+
151
164
  // src/ structure — include FILES so AI knows exact filenames + extensions
152
- for (const srcDir of ["src", "lib", "app"]) {
165
+ for (const srcDir of isMonorepo ? ["packages"] : ["src", "lib", "app"]) {
153
166
  if (existsSync(join(cwd, srcDir))) {
154
167
  const tree = execSync(
155
- `find ${srcDir} -maxdepth 3 -not -path '*/node_modules/*' -not -path '*/dist/*' -not -name '*.test.*' -not -name '*.spec.*' 2>/dev/null | sort | head -60`,
156
- { cwd, encoding: "utf8", timeout: 2000 }
168
+ `find ${srcDir} -maxdepth ${isMonorepo ? 4 : 3} -not -path '*/node_modules/*' -not -path '*/dist/*' -not -name '*.test.*' -not -name '*.spec.*' 2>/dev/null | sort | head -80`,
169
+ { cwd, encoding: "utf8", timeout: 3000 }
157
170
  ).trim();
158
171
  if (tree) parts.push(`Files in ${srcDir}/:\n${tree}`);
159
172
  break;
@@ -238,6 +251,8 @@ SEMANTIC MAPPING: When the user references a concept, search the file tree for R
238
251
  - When uncertain: grep -rn "keyword" src/ --include="*.ts" -l (list matching files)
239
252
 
240
253
  ACTION vs CONCEPTUAL: If the prompt starts with "run", "execute", "check", "test", "build", "show output of" — ALWAYS generate an executable command. NEVER read README for action requests. Only read docs for "explain why", "what does X mean", "how was X designed".
254
+
255
+ MONOREPO: If the project context says "MONOREPO", search packages/ or apps/ NOT src/. Use: grep -rn "pattern" packages/ --include="*.ts". For specific packages, use packages/PKGNAME/src/.
241
256
  cwd: ${process.cwd()}
242
257
  shell: zsh / macOS${projectContext}${restrictionBlock}${contextBlock}`;
243
258
  }