@ottili_one/ai-chat 1.0.1 → 1.0.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 (49) hide show
  1. package/README.md +89 -10
  2. package/dist/analytics/client.d.ts +2 -0
  3. package/dist/analytics/client.js +95 -0
  4. package/dist/analytics/client.js.map +1 -0
  5. package/dist/analytics/session.d.ts +15 -0
  6. package/dist/analytics/session.js +70 -0
  7. package/dist/analytics/session.js.map +1 -0
  8. package/dist/cli/commands.d.ts +2 -1
  9. package/dist/cli/commands.js +134 -90
  10. package/dist/cli/commands.js.map +1 -1
  11. package/dist/cli/repl.d.ts +4 -1
  12. package/dist/cli/repl.js +19 -1
  13. package/dist/cli/repl.js.map +1 -1
  14. package/dist/config/configurator.d.ts +18 -0
  15. package/dist/config/configurator.js +106 -0
  16. package/dist/config/configurator.js.map +1 -0
  17. package/dist/config/providerCatalog.d.ts +8 -0
  18. package/dist/config/providerCatalog.js +33 -0
  19. package/dist/config/providerCatalog.js.map +1 -0
  20. package/dist/config/userConfig.d.ts +2 -0
  21. package/dist/config/userConfig.js +68 -18
  22. package/dist/config/userConfig.js.map +1 -1
  23. package/dist/core/generateCommand.js +7 -2
  24. package/dist/core/generateCommand.js.map +1 -1
  25. package/dist/core/prompts.d.ts +1 -0
  26. package/dist/core/prompts.js +4 -0
  27. package/dist/core/prompts.js.map +1 -1
  28. package/dist/providers/anthropic.d.ts +8 -0
  29. package/dist/providers/anthropic.js +67 -0
  30. package/dist/providers/anthropic.js.map +1 -0
  31. package/dist/providers/factory.js +16 -1
  32. package/dist/providers/factory.js.map +1 -1
  33. package/dist/providers/google.d.ts +8 -0
  34. package/dist/providers/google.js +76 -0
  35. package/dist/providers/google.js.map +1 -0
  36. package/dist/providers/ollama.d.ts +8 -0
  37. package/dist/providers/ollama.js +67 -0
  38. package/dist/providers/ollama.js.map +1 -0
  39. package/dist/providers/openai.d.ts +2 -2
  40. package/dist/providers/openai.js +10 -6
  41. package/dist/providers/openai.js.map +1 -1
  42. package/dist/types/index.d.ts +28 -2
  43. package/dist/utils/branding.d.ts +1 -1
  44. package/dist/utils/branding.js +7 -2
  45. package/dist/utils/branding.js.map +1 -1
  46. package/dist/workspace/inspectWorkspace.d.ts +1 -0
  47. package/dist/workspace/inspectWorkspace.js +174 -0
  48. package/dist/workspace/inspectWorkspace.js.map +1 -0
  49. package/package.json +69 -69
@@ -0,0 +1,67 @@
1
+ import { ProviderError } from "../utils/errors.js";
2
+ export class AnthropicProvider {
3
+ config;
4
+ name = "anthropic";
5
+ constructor(config) {
6
+ this.config = config;
7
+ }
8
+ async generateObject(input) {
9
+ const controller = new AbortController();
10
+ const timeout = setTimeout(() => controller.abort(), this.config.timeoutMs);
11
+ try {
12
+ const response = await fetch(`${this.config.baseUrl}/messages`, {
13
+ method: "POST",
14
+ headers: {
15
+ "Content-Type": "application/json",
16
+ "anthropic-version": "2023-06-01",
17
+ "x-api-key": this.config.apiKey ?? ""
18
+ },
19
+ body: JSON.stringify({
20
+ model: this.config.model,
21
+ max_tokens: 1_024,
22
+ temperature: input.temperature ?? 0.1,
23
+ system: `${input.systemPrompt}\nReturn only a JSON object that matches the requested schema.`,
24
+ messages: [
25
+ {
26
+ role: "user",
27
+ content: input.userPrompt
28
+ }
29
+ ]
30
+ }),
31
+ signal: controller.signal
32
+ });
33
+ const data = (await response.json());
34
+ if (!response.ok) {
35
+ throw new ProviderError(data.error?.message
36
+ ? `Provider request failed: ${data.error.message}`
37
+ : `Provider request failed with status ${response.status}.`);
38
+ }
39
+ const rawText = data.content
40
+ ?.filter((block) => block.type === "text")
41
+ .map((block) => block.text)
42
+ .filter((block) => typeof block === "string")
43
+ .join("");
44
+ if (!rawText || rawText.trim().length === 0) {
45
+ throw new ProviderError("Provider returned an empty response.");
46
+ }
47
+ return {
48
+ provider: this.name,
49
+ model: this.config.model,
50
+ rawText
51
+ };
52
+ }
53
+ catch (error) {
54
+ if (error instanceof ProviderError) {
55
+ throw error;
56
+ }
57
+ if (error.name === "AbortError") {
58
+ throw new ProviderError(`Provider request timed out after ${this.config.timeoutMs}ms.`, error);
59
+ }
60
+ throw new ProviderError("Failed to reach AI provider.", error);
61
+ }
62
+ finally {
63
+ clearTimeout(timeout);
64
+ }
65
+ }
66
+ }
67
+ //# sourceMappingURL=anthropic.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"anthropic.js","sourceRoot":"","sources":["../../src/providers/anthropic.ts"],"names":[],"mappings":"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"}
@@ -1,8 +1,23 @@
1
1
  import { ConfigurationError } from "../utils/errors.js";
2
+ import { AnthropicProvider } from "./anthropic.js";
3
+ import { GoogleProvider } from "./google.js";
4
+ import { OllamaProvider } from "./ollama.js";
2
5
  import { OpenAICompatibleProvider } from "./openai.js";
3
6
  export function createProvider(config) {
4
7
  if (config.provider === "openai") {
5
- return new OpenAICompatibleProvider(config);
8
+ return new OpenAICompatibleProvider("openai", config);
9
+ }
10
+ if (config.provider === "anthropic") {
11
+ return new AnthropicProvider(config);
12
+ }
13
+ if (config.provider === "ollama") {
14
+ return new OllamaProvider(config);
15
+ }
16
+ if (config.provider === "google") {
17
+ return new GoogleProvider(config);
18
+ }
19
+ if (config.provider === "vllm") {
20
+ return new OpenAICompatibleProvider("vllm", config);
6
21
  }
7
22
  throw new ConfigurationError(`Unsupported AI provider: ${config.provider}`);
8
23
  }
@@ -1 +1 @@
1
- {"version":3,"file":"factory.js","sourceRoot":"","sources":["../../src/providers/factory.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AACxD,OAAO,EAAE,wBAAwB,EAAE,MAAM,aAAa,CAAC;AAEvD,MAAM,UAAU,cAAc,CAAC,MAAiB;IAC9C,IAAI,MAAM,CAAC,QAAQ,KAAK,QAAQ,EAAE,CAAC;QACjC,OAAO,IAAI,wBAAwB,CAAC,MAAM,CAAC,CAAC;IAC9C,CAAC;IAED,MAAM,IAAI,kBAAkB,CAAC,4BAA4B,MAAM,CAAC,QAAQ,EAAE,CAAC,CAAC;AAC9E,CAAC"}
1
+ {"version":3,"file":"factory.js","sourceRoot":"","sources":["../../src/providers/factory.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AACxD,OAAO,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AACnD,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,EAAE,wBAAwB,EAAE,MAAM,aAAa,CAAC;AAEvD,MAAM,UAAU,cAAc,CAAC,MAAiB;IAC9C,IAAI,MAAM,CAAC,QAAQ,KAAK,QAAQ,EAAE,CAAC;QACjC,OAAO,IAAI,wBAAwB,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;IACxD,CAAC;IAED,IAAI,MAAM,CAAC,QAAQ,KAAK,WAAW,EAAE,CAAC;QACpC,OAAO,IAAI,iBAAiB,CAAC,MAAM,CAAC,CAAC;IACvC,CAAC;IAED,IAAI,MAAM,CAAC,QAAQ,KAAK,QAAQ,EAAE,CAAC;QACjC,OAAO,IAAI,cAAc,CAAC,MAAM,CAAC,CAAC;IACpC,CAAC;IAED,IAAI,MAAM,CAAC,QAAQ,KAAK,QAAQ,EAAE,CAAC;QACjC,OAAO,IAAI,cAAc,CAAC,MAAM,CAAC,CAAC;IACpC,CAAC;IAED,IAAI,MAAM,CAAC,QAAQ,KAAK,MAAM,EAAE,CAAC;QAC/B,OAAO,IAAI,wBAAwB,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACtD,CAAC;IAED,MAAM,IAAI,kBAAkB,CAAC,4BAA4B,MAAM,CAAC,QAAQ,EAAE,CAAC,CAAC;AAC9E,CAAC"}
@@ -0,0 +1,8 @@
1
+ import type { AppConfig, GenerateObjectRequest, ProviderTextResponse } from "../types/index.js";
2
+ import type { AIProvider } from "./types.js";
3
+ export declare class GoogleProvider implements AIProvider {
4
+ private readonly config;
5
+ readonly name: "google";
6
+ constructor(config: AppConfig);
7
+ generateObject(input: GenerateObjectRequest): Promise<ProviderTextResponse>;
8
+ }
@@ -0,0 +1,76 @@
1
+ import { ProviderError } from "../utils/errors.js";
2
+ export class GoogleProvider {
3
+ config;
4
+ name = "google";
5
+ constructor(config) {
6
+ this.config = config;
7
+ }
8
+ async generateObject(input) {
9
+ const controller = new AbortController();
10
+ const timeout = setTimeout(() => controller.abort(), this.config.timeoutMs);
11
+ try {
12
+ const response = await fetch(`${this.config.baseUrl}/models/${encodeURIComponent(this.config.model)}:generateContent?key=${encodeURIComponent(this.config.apiKey ?? "")}`, {
13
+ method: "POST",
14
+ headers: {
15
+ "Content-Type": "application/json"
16
+ },
17
+ body: JSON.stringify({
18
+ systemInstruction: {
19
+ parts: [
20
+ {
21
+ text: input.systemPrompt
22
+ }
23
+ ]
24
+ },
25
+ contents: [
26
+ {
27
+ role: "user",
28
+ parts: [
29
+ {
30
+ text: input.userPrompt
31
+ }
32
+ ]
33
+ }
34
+ ],
35
+ generationConfig: {
36
+ temperature: input.temperature ?? 0.1,
37
+ responseMimeType: "application/json",
38
+ responseSchema: input.jsonSchema
39
+ }
40
+ }),
41
+ signal: controller.signal
42
+ });
43
+ const data = (await response.json());
44
+ if (!response.ok) {
45
+ throw new ProviderError(data.error?.message
46
+ ? `Provider request failed: ${data.error.message}`
47
+ : `Provider request failed with status ${response.status}.`);
48
+ }
49
+ const rawText = data.candidates?.[0]?.content?.parts
50
+ ?.map((part) => part.text)
51
+ .filter((part) => typeof part === "string")
52
+ .join("");
53
+ if (!rawText || rawText.trim().length === 0) {
54
+ throw new ProviderError("Provider returned an empty response.");
55
+ }
56
+ return {
57
+ provider: this.name,
58
+ model: this.config.model,
59
+ rawText
60
+ };
61
+ }
62
+ catch (error) {
63
+ if (error instanceof ProviderError) {
64
+ throw error;
65
+ }
66
+ if (error.name === "AbortError") {
67
+ throw new ProviderError(`Provider request timed out after ${this.config.timeoutMs}ms.`, error);
68
+ }
69
+ throw new ProviderError("Failed to reach AI provider.", error);
70
+ }
71
+ finally {
72
+ clearTimeout(timeout);
73
+ }
74
+ }
75
+ }
76
+ //# sourceMappingURL=google.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"google.js","sourceRoot":"","sources":["../../src/providers/google.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ import type { AppConfig, GenerateObjectRequest, ProviderTextResponse } from "../types/index.js";
2
+ import type { AIProvider } from "./types.js";
3
+ export declare class OllamaProvider implements AIProvider {
4
+ private readonly config;
5
+ readonly name: "ollama";
6
+ constructor(config: AppConfig);
7
+ generateObject(input: GenerateObjectRequest): Promise<ProviderTextResponse>;
8
+ }
@@ -0,0 +1,67 @@
1
+ import { ProviderError } from "../utils/errors.js";
2
+ export class OllamaProvider {
3
+ config;
4
+ name = "ollama";
5
+ constructor(config) {
6
+ this.config = config;
7
+ }
8
+ async generateObject(input) {
9
+ const controller = new AbortController();
10
+ const timeout = setTimeout(() => controller.abort(), this.config.timeoutMs);
11
+ try {
12
+ const response = await fetch(`${this.config.baseUrl}/chat`, {
13
+ method: "POST",
14
+ headers: {
15
+ "Content-Type": "application/json"
16
+ },
17
+ body: JSON.stringify({
18
+ model: this.config.model,
19
+ stream: false,
20
+ format: input.jsonSchema,
21
+ options: {
22
+ temperature: input.temperature ?? 0.1
23
+ },
24
+ messages: [
25
+ {
26
+ role: "system",
27
+ content: input.systemPrompt
28
+ },
29
+ {
30
+ role: "user",
31
+ content: input.userPrompt
32
+ }
33
+ ]
34
+ }),
35
+ signal: controller.signal
36
+ });
37
+ const data = (await response.json());
38
+ if (!response.ok) {
39
+ throw new ProviderError(data.error
40
+ ? `Provider request failed: ${data.error}`
41
+ : `Provider request failed with status ${response.status}.`);
42
+ }
43
+ const rawText = data.message?.content;
44
+ if (!rawText || rawText.trim().length === 0) {
45
+ throw new ProviderError("Provider returned an empty response.");
46
+ }
47
+ return {
48
+ provider: this.name,
49
+ model: data.model ?? this.config.model,
50
+ rawText
51
+ };
52
+ }
53
+ catch (error) {
54
+ if (error instanceof ProviderError) {
55
+ throw error;
56
+ }
57
+ if (error.name === "AbortError") {
58
+ throw new ProviderError(`Provider request timed out after ${this.config.timeoutMs}ms.`, error);
59
+ }
60
+ throw new ProviderError("Failed to reach AI provider.", error);
61
+ }
62
+ finally {
63
+ clearTimeout(timeout);
64
+ }
65
+ }
66
+ }
67
+ //# sourceMappingURL=ollama.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ollama.js","sourceRoot":"","sources":["../../src/providers/ollama.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAUnD,MAAM,OAAO,cAAc;IAGW;IAFpB,IAAI,GAAG,QAAiB,CAAC;IAEzC,YAAoC,MAAiB;QAAjB,WAAM,GAAN,MAAM,CAAW;IAAG,CAAC;IAElD,KAAK,CAAC,cAAc,CACzB,KAA4B;QAE5B,MAAM,UAAU,GAAG,IAAI,eAAe,EAAE,CAAC;QACzC,MAAM,OAAO,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,UAAU,CAAC,KAAK,EAAE,EAAE,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;QAE5E,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,OAAO,OAAO,EAAE;gBAC1D,MAAM,EAAE,MAAM;gBACd,OAAO,EAAE;oBACP,cAAc,EAAE,kBAAkB;iBACnC;gBACD,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC;oBACnB,KAAK,EAAE,IAAI,CAAC,MAAM,CAAC,KAAK;oBACxB,MAAM,EAAE,KAAK;oBACb,MAAM,EAAE,KAAK,CAAC,UAAU;oBACxB,OAAO,EAAE;wBACP,WAAW,EAAE,KAAK,CAAC,WAAW,IAAI,GAAG;qBACtC;oBACD,QAAQ,EAAE;wBACR;4BACE,IAAI,EAAE,QAAQ;4BACd,OAAO,EAAE,KAAK,CAAC,YAAY;yBAC5B;wBACD;4BACE,IAAI,EAAE,MAAM;4BACZ,OAAO,EAAE,KAAK,CAAC,UAAU;yBAC1B;qBACF;iBACF,CAAC;gBACF,MAAM,EAAE,UAAU,CAAC,MAAM;aAC1B,CAAC,CAAC;YAEH,MAAM,IAAI,GAAG,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAuB,CAAC;YAE3D,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;gBACjB,MAAM,IAAI,aAAa,CACrB,IAAI,CAAC,KAAK;oBACR,CAAC,CAAC,4BAA4B,IAAI,CAAC,KAAK,EAAE;oBAC1C,CAAC,CAAC,uCAAuC,QAAQ,CAAC,MAAM,GAAG,CAC9D,CAAC;YACJ,CAAC;YAED,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,EAAE,OAAO,CAAC;YAEtC,IAAI,CAAC,OAAO,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBAC5C,MAAM,IAAI,aAAa,CAAC,sCAAsC,CAAC,CAAC;YAClE,CAAC;YAED,OAAO;gBACL,QAAQ,EAAE,IAAI,CAAC,IAAI;gBACnB,KAAK,EAAE,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,MAAM,CAAC,KAAK;gBACtC,OAAO;aACR,CAAC;QACJ,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,KAAK,YAAY,aAAa,EAAE,CAAC;gBACnC,MAAM,KAAK,CAAC;YACd,CAAC;YAED,IAAK,KAAe,CAAC,IAAI,KAAK,YAAY,EAAE,CAAC;gBAC3C,MAAM,IAAI,aAAa,CACrB,oCAAoC,IAAI,CAAC,MAAM,CAAC,SAAS,KAAK,EAC9D,KAAK,CACN,CAAC;YACJ,CAAC;YAED,MAAM,IAAI,aAAa,CAAC,8BAA8B,EAAE,KAAK,CAAC,CAAC;QACjE,CAAC;gBAAS,CAAC;YACT,YAAY,CAAC,OAAO,CAAC,CAAC;QACxB,CAAC;IACH,CAAC;CACF"}
@@ -1,8 +1,8 @@
1
1
  import type { AppConfig, GenerateObjectRequest, ProviderTextResponse } from "../types/index.js";
2
2
  import type { AIProvider } from "./types.js";
3
3
  export declare class OpenAICompatibleProvider implements AIProvider {
4
+ readonly name: "openai" | "vllm";
4
5
  private readonly config;
5
- readonly name: "openai";
6
- constructor(config: AppConfig);
6
+ constructor(name: "openai" | "vllm", config: AppConfig);
7
7
  generateObject(input: GenerateObjectRequest): Promise<ProviderTextResponse>;
8
8
  }
@@ -1,20 +1,24 @@
1
1
  import { ProviderError } from "../utils/errors.js";
2
2
  export class OpenAICompatibleProvider {
3
+ name;
3
4
  config;
4
- name = "openai";
5
- constructor(config) {
5
+ constructor(name, config) {
6
+ this.name = name;
6
7
  this.config = config;
7
8
  }
8
9
  async generateObject(input) {
9
10
  const controller = new AbortController();
10
11
  const timeout = setTimeout(() => controller.abort(), this.config.timeoutMs);
11
12
  try {
13
+ const headers = {
14
+ "Content-Type": "application/json"
15
+ };
16
+ if (this.config.apiKey) {
17
+ headers.Authorization = `Bearer ${this.config.apiKey}`;
18
+ }
12
19
  const response = await fetch(`${this.config.baseUrl}/chat/completions`, {
13
20
  method: "POST",
14
- headers: {
15
- Authorization: `Bearer ${this.config.apiKey}`,
16
- "Content-Type": "application/json"
17
- },
21
+ headers,
18
22
  body: JSON.stringify({
19
23
  model: this.config.model,
20
24
  temperature: input.temperature ?? 0.1,
@@ -1 +1 @@
1
- {"version":3,"file":"openai.js","sourceRoot":"","sources":["../../src/providers/openai.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"openai.js","sourceRoot":"","sources":["../../src/providers/openai.ts"],"names":[],"mappings":"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"}
@@ -2,7 +2,7 @@ export type RiskLevel = "low" | "medium" | "high";
2
2
  export type OperatingSystem = "linux" | "macos" | "wsl" | "unix" | "unsupported";
3
3
  export type ShellType = "bash" | "zsh" | "sh" | "unknown";
4
4
  export type ServiceManager = "systemctl" | "service" | "rc-service" | "launchctl" | "unknown";
5
- export type ProviderName = "openai";
5
+ export type ProviderName = "openai" | "anthropic" | "ollama" | "google" | "vllm";
6
6
  export interface PlatformContext {
7
7
  os: OperatingSystem;
8
8
  shell: ShellType;
@@ -29,9 +29,11 @@ export interface CommandSuggestion extends ProviderCommandPayload {
29
29
  export interface AppConfig {
30
30
  provider: ProviderName;
31
31
  model: string;
32
- apiKey: string;
32
+ apiKey?: string;
33
33
  baseUrl: string;
34
34
  timeoutMs: number;
35
+ analytics: boolean;
36
+ analyticsId?: string;
35
37
  }
36
38
  export interface GenerateObjectRequest {
37
39
  systemPrompt: string;
@@ -56,6 +58,7 @@ export interface GenerateCommandOptions {
56
58
  provider: AIProvider;
57
59
  explainRequested?: boolean;
58
60
  history?: ConversationTurn[];
61
+ workspaceContext?: string;
59
62
  }
60
63
  export interface OutputOptions {
61
64
  color: boolean;
@@ -77,3 +80,26 @@ export interface PromptAdapter {
77
80
  confirm(message: string, initial?: boolean): Promise<boolean>;
78
81
  text(message: string): Promise<string>;
79
82
  }
83
+ export interface AnalyticsClient {
84
+ trackCliStart(payload: {
85
+ os: string;
86
+ shell: string;
87
+ provider: ProviderName;
88
+ mode: "interactive" | "one-shot";
89
+ }): Promise<void>;
90
+ trackPromptSent(payload: {
91
+ os: string;
92
+ shell: string;
93
+ provider: ProviderName;
94
+ mode: "interactive" | "one-shot";
95
+ }): Promise<void>;
96
+ trackError(payload: {
97
+ prompt?: string;
98
+ os?: string;
99
+ shell?: string;
100
+ provider?: ProviderName;
101
+ message: string;
102
+ code?: string;
103
+ time: string;
104
+ }): Promise<void>;
105
+ }
@@ -1,5 +1,5 @@
1
1
  export declare const APP_NAME = "AI-CMD";
2
- export declare const APP_VERSION = "1.0.1";
2
+ export declare const APP_VERSION = "1.0.3";
3
3
  export declare const BRAND_NAME = "Ottili ONE";
4
4
  export declare const BRAND_URL = "ottili.one";
5
5
  export declare function formatVersionBanner(): string;
@@ -1,9 +1,14 @@
1
1
  export const APP_NAME = "AI-CMD";
2
- export const APP_VERSION = "1.0.1";
2
+ export const APP_VERSION = "1.0.3";
3
3
  export const BRAND_NAME = "Ottili ONE";
4
4
  export const BRAND_URL = "ottili.one";
5
5
  export function formatVersionBanner() {
6
- return [APP_NAME, `v. ${APP_VERSION}`, `Powered by ${BRAND_NAME}`, BRAND_URL].join("\n");
6
+ return [
7
+ APP_NAME,
8
+ `v. ${APP_VERSION}`,
9
+ `Powered by ${BRAND_NAME}`,
10
+ BRAND_URL
11
+ ].join("\n");
7
12
  }
8
13
  export function formatReplBanner() {
9
14
  return `${APP_NAME} | Powered by ${BRAND_NAME} | ${BRAND_URL}`;
@@ -1 +1 @@
1
- {"version":3,"file":"branding.js","sourceRoot":"","sources":["../../src/utils/branding.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,QAAQ,GAAG,QAAQ,CAAC;AACjC,MAAM,CAAC,MAAM,WAAW,GAAG,OAAO,CAAC;AACnC,MAAM,CAAC,MAAM,UAAU,GAAG,YAAY,CAAC;AACvC,MAAM,CAAC,MAAM,SAAS,GAAG,YAAY,CAAC;AAEtC,MAAM,UAAU,mBAAmB;IACjC,OAAO,CAAC,QAAQ,EAAE,MAAM,WAAW,EAAE,EAAE,cAAc,UAAU,EAAE,EAAE,SAAS,CAAC,CAAC,IAAI,CAChF,IAAI,CACL,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,gBAAgB;IAC9B,OAAO,GAAG,QAAQ,iBAAiB,UAAU,MAAM,SAAS,EAAE,CAAC;AACjE,CAAC"}
1
+ {"version":3,"file":"branding.js","sourceRoot":"","sources":["../../src/utils/branding.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,QAAQ,GAAG,QAAQ,CAAC;AACjC,MAAM,CAAC,MAAM,WAAW,GAAG,OAAO,CAAC;AACnC,MAAM,CAAC,MAAM,UAAU,GAAG,YAAY,CAAC;AACvC,MAAM,CAAC,MAAM,SAAS,GAAG,YAAY,CAAC;AAEtC,MAAM,UAAU,mBAAmB;IACjC,OAAO;QACL,QAAQ;QACR,MAAM,WAAW,EAAE;QACnB,cAAc,UAAU,EAAE;QAC1B,SAAS;KACV,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACf,CAAC;AAED,MAAM,UAAU,gBAAgB;IAC9B,OAAO,GAAG,QAAQ,iBAAiB,UAAU,MAAM,SAAS,EAAE,CAAC;AACjE,CAAC"}
@@ -0,0 +1 @@
1
+ export declare function inspectWorkspace(cwd: string): Promise<string | undefined>;
@@ -0,0 +1,174 @@
1
+ import { readdir, readFile } from "node:fs/promises";
2
+ import path from "node:path";
3
+ const IGNORED_NAMES = new Set([
4
+ ".git",
5
+ ".idea",
6
+ ".vscode",
7
+ "node_modules",
8
+ "dist",
9
+ "build",
10
+ "coverage",
11
+ ".next",
12
+ ".nuxt",
13
+ ".turbo"
14
+ ]);
15
+ async function listTree(root, currentDir, depth, limit) {
16
+ if (depth < 0 || limit.remaining <= 0) {
17
+ return [];
18
+ }
19
+ let entries;
20
+ try {
21
+ entries = await readdir(currentDir, { withFileTypes: true });
22
+ }
23
+ catch {
24
+ return [];
25
+ }
26
+ const visibleEntries = entries
27
+ .filter((entry) => !IGNORED_NAMES.has(entry.name))
28
+ .sort((left, right) => left.name.localeCompare(right.name));
29
+ const preview = [];
30
+ for (const entry of visibleEntries) {
31
+ if (limit.remaining <= 0) {
32
+ break;
33
+ }
34
+ const absolutePath = path.join(currentDir, entry.name);
35
+ const relativePath = path.relative(root, absolutePath) || entry.name;
36
+ preview.push(entry.isDirectory() ? `${relativePath}/` : relativePath);
37
+ limit.remaining -= 1;
38
+ if (entry.isDirectory() && depth > 0 && limit.remaining > 0) {
39
+ preview.push(...(await listTree(root, absolutePath, depth - 1, limit)));
40
+ }
41
+ }
42
+ return preview;
43
+ }
44
+ function parsePackageJson(rawText) {
45
+ try {
46
+ const parsed = JSON.parse(rawText);
47
+ const dependencies = [
48
+ ...Object.keys(parsed.dependencies ?? {}),
49
+ ...Object.keys(parsed.devDependencies ?? {})
50
+ ].slice(0, 10);
51
+ return {
52
+ ...(parsed.name ? { name: parsed.name } : {}),
53
+ ...(parsed.packageManager
54
+ ? { packageManager: parsed.packageManager }
55
+ : {}),
56
+ scripts: Object.keys(parsed.scripts ?? {}).slice(0, 10),
57
+ dependencies
58
+ };
59
+ }
60
+ catch {
61
+ return undefined;
62
+ }
63
+ }
64
+ function parseMakeTargets(rawText) {
65
+ return rawText
66
+ .split(/\r?\n/u)
67
+ .map((line) => line.match(/^([A-Za-z0-9][^:\s=]+):(?:\s|$)/u)?.[1])
68
+ .filter((target) => Boolean(target))
69
+ .filter((target) => !target.startsWith("."))
70
+ .slice(0, 10);
71
+ }
72
+ function parseCargoPackage(rawText) {
73
+ const match = rawText.match(/^\s*name\s*=\s*"([^"]+)"/mu);
74
+ return match?.[1];
75
+ }
76
+ function parseGoModule(rawText) {
77
+ const match = rawText.match(/^module\s+(.+)$/mu);
78
+ return match?.[1]?.trim();
79
+ }
80
+ function parseDockerServices(rawText) {
81
+ const servicesBlock = rawText.match(/^\s*services:\s*([\s\S]+)$/mu)?.[1];
82
+ if (!servicesBlock) {
83
+ return [];
84
+ }
85
+ return Array.from(servicesBlock.matchAll(/^\s{2}([A-Za-z0-9._-]+):\s*$/gmu))
86
+ .map((match) => match[1])
87
+ .filter((service) => Boolean(service))
88
+ .slice(0, 10);
89
+ }
90
+ export async function inspectWorkspace(cwd) {
91
+ let topLevelEntries;
92
+ try {
93
+ topLevelEntries = await readdir(cwd, { withFileTypes: true });
94
+ }
95
+ catch {
96
+ return undefined;
97
+ }
98
+ const visibleTopLevelEntries = topLevelEntries
99
+ .filter((entry) => !IGNORED_NAMES.has(entry.name))
100
+ .sort((left, right) => left.name.localeCompare(right.name));
101
+ const summary = {
102
+ topLevelEntries: visibleTopLevelEntries
103
+ .slice(0, 20)
104
+ .map((entry) => (entry.isDirectory() ? `${entry.name}/` : entry.name)),
105
+ treePreview: await listTree(cwd, cwd, 1, { remaining: 25 }),
106
+ projectHints: []
107
+ };
108
+ const fileReaders = [];
109
+ const maybeReadFile = (fileName, onContent) => {
110
+ if (!visibleTopLevelEntries.some((entry) => entry.name === fileName)) {
111
+ return;
112
+ }
113
+ fileReaders.push(readFile(path.join(cwd, fileName), "utf8")
114
+ .then(onContent)
115
+ .catch(() => undefined));
116
+ };
117
+ if (visibleTopLevelEntries.some((entry) => entry.name === "package.json")) {
118
+ summary.projectHints.push("node");
119
+ }
120
+ if (visibleTopLevelEntries.some((entry) => [
121
+ "docker-compose.yml",
122
+ "docker-compose.yaml",
123
+ "compose.yml",
124
+ "compose.yaml"
125
+ ].includes(entry.name))) {
126
+ summary.projectHints.push("docker-compose");
127
+ }
128
+ if (visibleTopLevelEntries.some((entry) => entry.name === "Dockerfile")) {
129
+ summary.projectHints.push("docker");
130
+ }
131
+ if (visibleTopLevelEntries.some((entry) => entry.name === "Cargo.toml")) {
132
+ summary.projectHints.push("rust");
133
+ }
134
+ if (visibleTopLevelEntries.some((entry) => entry.name === "go.mod")) {
135
+ summary.projectHints.push("go");
136
+ }
137
+ if (visibleTopLevelEntries.some((entry) => entry.name === "pyproject.toml")) {
138
+ summary.projectHints.push("python");
139
+ }
140
+ maybeReadFile("package.json", (rawText) => {
141
+ const packageJson = parsePackageJson(rawText);
142
+ if (packageJson) {
143
+ summary.packageJson = packageJson;
144
+ }
145
+ });
146
+ maybeReadFile("Makefile", (rawText) => {
147
+ summary.makeTargets = parseMakeTargets(rawText);
148
+ });
149
+ maybeReadFile("Cargo.toml", (rawText) => {
150
+ const cargoPackage = parseCargoPackage(rawText);
151
+ if (cargoPackage) {
152
+ summary.cargoPackage = cargoPackage;
153
+ }
154
+ });
155
+ maybeReadFile("go.mod", (rawText) => {
156
+ const goModule = parseGoModule(rawText);
157
+ if (goModule) {
158
+ summary.goModule = goModule;
159
+ }
160
+ });
161
+ for (const composeFile of [
162
+ "docker-compose.yml",
163
+ "docker-compose.yaml",
164
+ "compose.yml",
165
+ "compose.yaml"
166
+ ]) {
167
+ maybeReadFile(composeFile, (rawText) => {
168
+ summary.docker = parseDockerServices(rawText);
169
+ });
170
+ }
171
+ await Promise.all(fileReaders);
172
+ return JSON.stringify(summary, null, 2);
173
+ }
174
+ //# sourceMappingURL=inspectWorkspace.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"inspectWorkspace.js","sourceRoot":"","sources":["../../src/workspace/inspectWorkspace.ts"],"names":[],"mappings":"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"}