@sunilp-org/jam-cli 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 (163) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +625 -0
  3. package/dist/commands/ask.d.ts +9 -0
  4. package/dist/commands/ask.d.ts.map +1 -0
  5. package/dist/commands/ask.js +84 -0
  6. package/dist/commands/ask.js.map +1 -0
  7. package/dist/commands/auth.d.ts +4 -0
  8. package/dist/commands/auth.d.ts.map +1 -0
  9. package/dist/commands/auth.js +44 -0
  10. package/dist/commands/auth.js.map +1 -0
  11. package/dist/commands/chat.d.ts +10 -0
  12. package/dist/commands/chat.d.ts.map +1 -0
  13. package/dist/commands/chat.js +57 -0
  14. package/dist/commands/chat.js.map +1 -0
  15. package/dist/commands/completion.d.ts +4 -0
  16. package/dist/commands/completion.d.ts.map +1 -0
  17. package/dist/commands/completion.js +156 -0
  18. package/dist/commands/completion.js.map +1 -0
  19. package/dist/commands/config.d.ts +6 -0
  20. package/dist/commands/config.d.ts.map +1 -0
  21. package/dist/commands/config.js +59 -0
  22. package/dist/commands/config.js.map +1 -0
  23. package/dist/commands/diff.d.ts +9 -0
  24. package/dist/commands/diff.d.ts.map +1 -0
  25. package/dist/commands/diff.js +69 -0
  26. package/dist/commands/diff.js.map +1 -0
  27. package/dist/commands/doctor.d.ts +3 -0
  28. package/dist/commands/doctor.d.ts.map +1 -0
  29. package/dist/commands/doctor.js +86 -0
  30. package/dist/commands/doctor.js.map +1 -0
  31. package/dist/commands/explain.d.ts +7 -0
  32. package/dist/commands/explain.d.ts.map +1 -0
  33. package/dist/commands/explain.js +72 -0
  34. package/dist/commands/explain.js.map +1 -0
  35. package/dist/commands/history.d.ts +3 -0
  36. package/dist/commands/history.d.ts.map +1 -0
  37. package/dist/commands/history.js +99 -0
  38. package/dist/commands/history.js.map +1 -0
  39. package/dist/commands/models.d.ts +3 -0
  40. package/dist/commands/models.d.ts.map +1 -0
  41. package/dist/commands/models.js +39 -0
  42. package/dist/commands/models.js.map +1 -0
  43. package/dist/commands/patch.d.ts +8 -0
  44. package/dist/commands/patch.d.ts.map +1 -0
  45. package/dist/commands/patch.js +158 -0
  46. package/dist/commands/patch.js.map +1 -0
  47. package/dist/commands/run.d.ts +6 -0
  48. package/dist/commands/run.d.ts.map +1 -0
  49. package/dist/commands/run.js +241 -0
  50. package/dist/commands/run.js.map +1 -0
  51. package/dist/commands/search.d.ts +9 -0
  52. package/dist/commands/search.d.ts.map +1 -0
  53. package/dist/commands/search.js +128 -0
  54. package/dist/commands/search.js.map +1 -0
  55. package/dist/config/defaults.d.ts +3 -0
  56. package/dist/config/defaults.d.ts.map +1 -0
  57. package/dist/config/defaults.js +16 -0
  58. package/dist/config/defaults.js.map +1 -0
  59. package/dist/config/loader.d.ts +4 -0
  60. package/dist/config/loader.d.ts.map +1 -0
  61. package/dist/config/loader.js +103 -0
  62. package/dist/config/loader.js.map +1 -0
  63. package/dist/config/schema.d.ts +104 -0
  64. package/dist/config/schema.d.ts.map +1 -0
  65. package/dist/config/schema.js +21 -0
  66. package/dist/config/schema.js.map +1 -0
  67. package/dist/index.d.ts +3 -0
  68. package/dist/index.d.ts.map +1 -0
  69. package/dist/index.js +249 -0
  70. package/dist/index.js.map +1 -0
  71. package/dist/providers/base.d.ts +32 -0
  72. package/dist/providers/base.d.ts.map +1 -0
  73. package/dist/providers/base.js +2 -0
  74. package/dist/providers/base.js.map +1 -0
  75. package/dist/providers/factory.d.ts +4 -0
  76. package/dist/providers/factory.d.ts.map +1 -0
  77. package/dist/providers/factory.js +13 -0
  78. package/dist/providers/factory.js.map +1 -0
  79. package/dist/providers/ollama.d.ts +14 -0
  80. package/dist/providers/ollama.d.ts.map +1 -0
  81. package/dist/providers/ollama.js +152 -0
  82. package/dist/providers/ollama.js.map +1 -0
  83. package/dist/storage/history.d.ts +21 -0
  84. package/dist/storage/history.d.ts.map +1 -0
  85. package/dist/storage/history.js +103 -0
  86. package/dist/storage/history.js.map +1 -0
  87. package/dist/tools/apply_patch.d.ts +3 -0
  88. package/dist/tools/apply_patch.d.ts.map +1 -0
  89. package/dist/tools/apply_patch.js +86 -0
  90. package/dist/tools/apply_patch.js.map +1 -0
  91. package/dist/tools/git_diff.d.ts +3 -0
  92. package/dist/tools/git_diff.d.ts.map +1 -0
  93. package/dist/tools/git_diff.js +49 -0
  94. package/dist/tools/git_diff.js.map +1 -0
  95. package/dist/tools/git_status.d.ts +3 -0
  96. package/dist/tools/git_status.d.ts.map +1 -0
  97. package/dist/tools/git_status.js +26 -0
  98. package/dist/tools/git_status.js.map +1 -0
  99. package/dist/tools/index.d.ts +10 -0
  100. package/dist/tools/index.d.ts.map +1 -0
  101. package/dist/tools/index.js +10 -0
  102. package/dist/tools/index.js.map +1 -0
  103. package/dist/tools/list_dir.d.ts +3 -0
  104. package/dist/tools/list_dir.d.ts.map +1 -0
  105. package/dist/tools/list_dir.js +61 -0
  106. package/dist/tools/list_dir.js.map +1 -0
  107. package/dist/tools/read_file.d.ts +3 -0
  108. package/dist/tools/read_file.d.ts.map +1 -0
  109. package/dist/tools/read_file.js +83 -0
  110. package/dist/tools/read_file.js.map +1 -0
  111. package/dist/tools/registry.d.ts +12 -0
  112. package/dist/tools/registry.d.ts.map +1 -0
  113. package/dist/tools/registry.js +76 -0
  114. package/dist/tools/registry.js.map +1 -0
  115. package/dist/tools/run_command.d.ts +6 -0
  116. package/dist/tools/run_command.d.ts.map +1 -0
  117. package/dist/tools/run_command.js +37 -0
  118. package/dist/tools/run_command.js.map +1 -0
  119. package/dist/tools/search_text.d.ts +3 -0
  120. package/dist/tools/search_text.d.ts.map +1 -0
  121. package/dist/tools/search_text.js +171 -0
  122. package/dist/tools/search_text.js.map +1 -0
  123. package/dist/tools/types.d.ts +25 -0
  124. package/dist/tools/types.d.ts.map +1 -0
  125. package/dist/tools/types.js +2 -0
  126. package/dist/tools/types.js.map +1 -0
  127. package/dist/tools/write_file.d.ts +3 -0
  128. package/dist/tools/write_file.d.ts.map +1 -0
  129. package/dist/tools/write_file.js +61 -0
  130. package/dist/tools/write_file.js.map +1 -0
  131. package/dist/ui/chat.d.ts +10 -0
  132. package/dist/ui/chat.d.ts.map +1 -0
  133. package/dist/ui/chat.js +173 -0
  134. package/dist/ui/chat.js.map +1 -0
  135. package/dist/ui/logo.d.ts +14 -0
  136. package/dist/ui/logo.d.ts.map +1 -0
  137. package/dist/ui/logo.js +76 -0
  138. package/dist/ui/logo.js.map +1 -0
  139. package/dist/ui/renderer.d.ts +15 -0
  140. package/dist/ui/renderer.d.ts.map +1 -0
  141. package/dist/ui/renderer.js +61 -0
  142. package/dist/ui/renderer.js.map +1 -0
  143. package/dist/utils/errors.d.ts +14 -0
  144. package/dist/utils/errors.d.ts.map +1 -0
  145. package/dist/utils/errors.js +26 -0
  146. package/dist/utils/errors.js.map +1 -0
  147. package/dist/utils/logger.d.ts +17 -0
  148. package/dist/utils/logger.d.ts.map +1 -0
  149. package/dist/utils/logger.js +50 -0
  150. package/dist/utils/logger.js.map +1 -0
  151. package/dist/utils/secrets.d.ts +4 -0
  152. package/dist/utils/secrets.d.ts.map +1 -0
  153. package/dist/utils/secrets.js +39 -0
  154. package/dist/utils/secrets.js.map +1 -0
  155. package/dist/utils/stream.d.ts +12 -0
  156. package/dist/utils/stream.d.ts.map +1 -0
  157. package/dist/utils/stream.js +54 -0
  158. package/dist/utils/stream.js.map +1 -0
  159. package/dist/utils/workspace.d.ts +14 -0
  160. package/dist/utils/workspace.d.ts.map +1 -0
  161. package/dist/utils/workspace.js +39 -0
  162. package/dist/utils/workspace.js.map +1 -0
  163. package/package.json +84 -0
@@ -0,0 +1,104 @@
1
+ import { z } from 'zod';
2
+ export declare const ToolPolicySchema: z.ZodEnum<["ask_every_time", "allowlist", "never"]>;
3
+ export type ToolPolicy = z.infer<typeof ToolPolicySchema>;
4
+ export declare const ProfileSchema: z.ZodObject<{
5
+ provider: z.ZodDefault<z.ZodString>;
6
+ model: z.ZodOptional<z.ZodString>;
7
+ baseUrl: z.ZodOptional<z.ZodString>;
8
+ apiKey: z.ZodOptional<z.ZodString>;
9
+ temperature: z.ZodOptional<z.ZodNumber>;
10
+ maxTokens: z.ZodOptional<z.ZodNumber>;
11
+ systemPrompt: z.ZodOptional<z.ZodString>;
12
+ }, "strip", z.ZodTypeAny, {
13
+ provider: string;
14
+ model?: string | undefined;
15
+ baseUrl?: string | undefined;
16
+ apiKey?: string | undefined;
17
+ temperature?: number | undefined;
18
+ maxTokens?: number | undefined;
19
+ systemPrompt?: string | undefined;
20
+ }, {
21
+ provider?: string | undefined;
22
+ model?: string | undefined;
23
+ baseUrl?: string | undefined;
24
+ apiKey?: string | undefined;
25
+ temperature?: number | undefined;
26
+ maxTokens?: number | undefined;
27
+ systemPrompt?: string | undefined;
28
+ }>;
29
+ export type Profile = z.infer<typeof ProfileSchema>;
30
+ export declare const JamConfigSchema: z.ZodObject<{
31
+ defaultProfile: z.ZodDefault<z.ZodString>;
32
+ profiles: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodObject<{
33
+ provider: z.ZodDefault<z.ZodString>;
34
+ model: z.ZodOptional<z.ZodString>;
35
+ baseUrl: z.ZodOptional<z.ZodString>;
36
+ apiKey: z.ZodOptional<z.ZodString>;
37
+ temperature: z.ZodOptional<z.ZodNumber>;
38
+ maxTokens: z.ZodOptional<z.ZodNumber>;
39
+ systemPrompt: z.ZodOptional<z.ZodString>;
40
+ }, "strip", z.ZodTypeAny, {
41
+ provider: string;
42
+ model?: string | undefined;
43
+ baseUrl?: string | undefined;
44
+ apiKey?: string | undefined;
45
+ temperature?: number | undefined;
46
+ maxTokens?: number | undefined;
47
+ systemPrompt?: string | undefined;
48
+ }, {
49
+ provider?: string | undefined;
50
+ model?: string | undefined;
51
+ baseUrl?: string | undefined;
52
+ apiKey?: string | undefined;
53
+ temperature?: number | undefined;
54
+ maxTokens?: number | undefined;
55
+ systemPrompt?: string | undefined;
56
+ }>>>;
57
+ toolPolicy: z.ZodDefault<z.ZodEnum<["ask_every_time", "allowlist", "never"]>>;
58
+ toolAllowlist: z.ZodDefault<z.ZodArray<z.ZodString, "many">>;
59
+ historyEnabled: z.ZodDefault<z.ZodBoolean>;
60
+ logLevel: z.ZodDefault<z.ZodEnum<["silent", "error", "warn", "info", "debug"]>>;
61
+ redactPatterns: z.ZodDefault<z.ZodArray<z.ZodString, "many">>;
62
+ }, "strip", z.ZodTypeAny, {
63
+ defaultProfile: string;
64
+ profiles: Record<string, {
65
+ provider: string;
66
+ model?: string | undefined;
67
+ baseUrl?: string | undefined;
68
+ apiKey?: string | undefined;
69
+ temperature?: number | undefined;
70
+ maxTokens?: number | undefined;
71
+ systemPrompt?: string | undefined;
72
+ }>;
73
+ toolPolicy: "ask_every_time" | "allowlist" | "never";
74
+ toolAllowlist: string[];
75
+ historyEnabled: boolean;
76
+ logLevel: "silent" | "error" | "warn" | "info" | "debug";
77
+ redactPatterns: string[];
78
+ }, {
79
+ defaultProfile?: string | undefined;
80
+ profiles?: Record<string, {
81
+ provider?: string | undefined;
82
+ model?: string | undefined;
83
+ baseUrl?: string | undefined;
84
+ apiKey?: string | undefined;
85
+ temperature?: number | undefined;
86
+ maxTokens?: number | undefined;
87
+ systemPrompt?: string | undefined;
88
+ }> | undefined;
89
+ toolPolicy?: "ask_every_time" | "allowlist" | "never" | undefined;
90
+ toolAllowlist?: string[] | undefined;
91
+ historyEnabled?: boolean | undefined;
92
+ logLevel?: "silent" | "error" | "warn" | "info" | "debug" | undefined;
93
+ redactPatterns?: string[] | undefined;
94
+ }>;
95
+ export type JamConfig = z.infer<typeof JamConfigSchema>;
96
+ export type CliOverrides = {
97
+ profile?: string;
98
+ provider?: string;
99
+ model?: string;
100
+ baseUrl?: string;
101
+ json?: boolean;
102
+ noColor?: boolean;
103
+ };
104
+ //# sourceMappingURL=schema.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../../src/config/schema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,eAAO,MAAM,gBAAgB,qDAAmD,CAAC;AACjF,MAAM,MAAM,UAAU,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gBAAgB,CAAC,CAAC;AAE1D,eAAO,MAAM,aAAa;;;;;;;;;;;;;;;;;;;;;;;;EAQxB,CAAC;AACH,MAAM,MAAM,OAAO,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,aAAa,CAAC,CAAC;AAEpD,eAAO,MAAM,eAAe;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAQ1B,CAAC;AACH,MAAM,MAAM,SAAS,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,eAAe,CAAC,CAAC;AAExD,MAAM,MAAM,YAAY,GAAG;IACzB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB,CAAC"}
@@ -0,0 +1,21 @@
1
+ import { z } from 'zod';
2
+ export const ToolPolicySchema = z.enum(['ask_every_time', 'allowlist', 'never']);
3
+ export const ProfileSchema = z.object({
4
+ provider: z.string().default('ollama'),
5
+ model: z.string().optional(),
6
+ baseUrl: z.string().url().optional(),
7
+ apiKey: z.string().optional(),
8
+ temperature: z.number().min(0).max(2).optional(),
9
+ maxTokens: z.number().int().positive().optional(),
10
+ systemPrompt: z.string().optional(),
11
+ });
12
+ export const JamConfigSchema = z.object({
13
+ defaultProfile: z.string().default('default'),
14
+ profiles: z.record(ProfileSchema).default({}),
15
+ toolPolicy: ToolPolicySchema.default('ask_every_time'),
16
+ toolAllowlist: z.array(z.string()).default([]),
17
+ historyEnabled: z.boolean().default(true),
18
+ logLevel: z.enum(['silent', 'error', 'warn', 'info', 'debug']).default('warn'),
19
+ redactPatterns: z.array(z.string()).default([]),
20
+ });
21
+ //# sourceMappingURL=schema.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schema.js","sourceRoot":"","sources":["../../src/config/schema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,gBAAgB,EAAE,WAAW,EAAE,OAAO,CAAC,CAAC,CAAC;AAGjF,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,CAAC,MAAM,CAAC;IACpC,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,OAAO,CAAC,QAAQ,CAAC;IACtC,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAC5B,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE;IACpC,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAC7B,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE;IAChD,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE;IACjD,YAAY,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;CACpC,CAAC,CAAC;AAGH,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,CAAC,MAAM,CAAC;IACtC,cAAc,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,OAAO,CAAC,SAAS,CAAC;IAC7C,QAAQ,EAAE,CAAC,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC;IAC7C,UAAU,EAAE,gBAAgB,CAAC,OAAO,CAAC,gBAAgB,CAAC;IACtD,aAAa,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC;IAC9C,cAAc,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC;IACzC,QAAQ,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC;IAC9E,cAAc,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC;CAChD,CAAC,CAAC"}
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":""}
package/dist/index.js ADDED
@@ -0,0 +1,249 @@
1
+ #!/usr/bin/env node
2
+ import { program } from 'commander';
3
+ import { fileURLToPath } from 'node:url';
4
+ import { dirname, join } from 'node:path';
5
+ import { readFileSync } from 'node:fs';
6
+ import { LOGO_PLAIN, printLogo } from './ui/logo.js';
7
+ const __filename = fileURLToPath(import.meta.url);
8
+ const __dirname = dirname(__filename);
9
+ const pkg = JSON.parse(readFileSync(join(__dirname, '..', 'package.json'), 'utf-8'));
10
+ // ── Global options ────────────────────────────────────────────────────────────
11
+ program
12
+ .name('jam')
13
+ .description('Jam — developer-first AI assistant CLI')
14
+ .version(pkg.version)
15
+ .addHelpText('before', `\n${LOGO_PLAIN}\n`)
16
+ .option('--profile <name>', 'use a specific config profile')
17
+ .option('--provider <name>', 'override the AI provider')
18
+ .option('--model <name>', 'override the model')
19
+ .option('--base-url <url>', 'override the provider base URL')
20
+ .option('--no-color', 'disable color output')
21
+ .option('--verbose', 'enable debug logging');
22
+ // ── Helpers ───────────────────────────────────────────────────────────────────
23
+ function globalOpts() {
24
+ return program.opts();
25
+ }
26
+ // ── ask ───────────────────────────────────────────────────────────────────────
27
+ program
28
+ .command('ask [prompt]')
29
+ .description('Send a one-shot question to the AI')
30
+ .option('--file <path>', 'read prompt from file')
31
+ .option('--json', 'output response as JSON')
32
+ .option('--system <prompt>', 'override the system prompt')
33
+ .action(async (prompt, cmdOpts) => {
34
+ const g = globalOpts();
35
+ const { runAsk } = await import('./commands/ask.js');
36
+ await runAsk(prompt, {
37
+ profile: g.profile,
38
+ provider: g.provider,
39
+ model: g.model,
40
+ baseUrl: g.baseUrl,
41
+ noColor: g.color === false,
42
+ file: cmdOpts['file'],
43
+ json: cmdOpts['json'],
44
+ system: cmdOpts['system'],
45
+ });
46
+ });
47
+ // ── chat ──────────────────────────────────────────────────────────────────────
48
+ program
49
+ .command('chat')
50
+ .description('Start an interactive multi-turn chat session')
51
+ .option('--resume <sessionId>', 'resume a previous session')
52
+ .option('--name <name>', 'name for the new session')
53
+ .action(async (cmdOpts) => {
54
+ const g = globalOpts();
55
+ const { runChat } = await import('./commands/chat.js');
56
+ await runChat({
57
+ profile: g.profile,
58
+ provider: g.provider,
59
+ model: g.model,
60
+ baseUrl: g.baseUrl,
61
+ resume: cmdOpts['resume'],
62
+ name: cmdOpts['name'],
63
+ });
64
+ });
65
+ // ── run ───────────────────────────────────────────────────────────────────────
66
+ program
67
+ .command('run [instruction]')
68
+ .description('Execute a task workflow using AI and local tools')
69
+ .action(async (instruction) => {
70
+ const g = globalOpts();
71
+ const { runRun } = await import('./commands/run.js');
72
+ await runRun(instruction, {
73
+ profile: g.profile,
74
+ provider: g.provider,
75
+ model: g.model,
76
+ baseUrl: g.baseUrl,
77
+ noColor: g.color === false,
78
+ });
79
+ });
80
+ // ── explain ───────────────────────────────────────────────────────────────────
81
+ program
82
+ .command('explain <path...>')
83
+ .description('Explain the contents of one or more files')
84
+ .option('--json', 'output response as JSON')
85
+ .action(async (paths, cmdOpts) => {
86
+ const g = globalOpts();
87
+ const { runExplain } = await import('./commands/explain.js');
88
+ await runExplain(paths, {
89
+ profile: g.profile,
90
+ provider: g.provider,
91
+ model: g.model,
92
+ baseUrl: g.baseUrl,
93
+ noColor: g.color === false,
94
+ json: cmdOpts['json'],
95
+ });
96
+ });
97
+ // ── search ────────────────────────────────────────────────────────────────────
98
+ program
99
+ .command('search [query]')
100
+ .description('Search the codebase for text or patterns')
101
+ .option('--glob <pattern>', 'limit search to files matching glob')
102
+ .option('--max-results <n>', 'maximum number of results', '20')
103
+ .option('--ask', 'pipe results to AI for explanation')
104
+ .option('--json', 'output as JSON (with --ask)')
105
+ .action(async (query, cmdOpts) => {
106
+ const g = globalOpts();
107
+ const { runSearch } = await import('./commands/search.js');
108
+ await runSearch(query, {
109
+ profile: g.profile,
110
+ provider: g.provider,
111
+ model: g.model,
112
+ baseUrl: g.baseUrl,
113
+ glob: cmdOpts['glob'],
114
+ maxResults: cmdOpts['maxResults'] ? parseInt(String(cmdOpts['maxResults']), 10) : undefined,
115
+ ask: cmdOpts['ask'],
116
+ json: cmdOpts['json'],
117
+ });
118
+ });
119
+ // ── diff ──────────────────────────────────────────────────────────────────────
120
+ program
121
+ .command('diff')
122
+ .description('Review a git diff with AI')
123
+ .option('--staged', 'review staged changes')
124
+ .option('--path <path>', 'limit diff to a specific path')
125
+ .option('--no-review', 'just show the diff, no AI review')
126
+ .option('--json', 'output as JSON')
127
+ .action(async (cmdOpts) => {
128
+ const g = globalOpts();
129
+ const { runDiff } = await import('./commands/diff.js');
130
+ await runDiff({
131
+ profile: g.profile,
132
+ provider: g.provider,
133
+ model: g.model,
134
+ baseUrl: g.baseUrl,
135
+ staged: cmdOpts['staged'],
136
+ path: cmdOpts['path'],
137
+ noReview: cmdOpts['review'] === false,
138
+ json: cmdOpts['json'],
139
+ });
140
+ });
141
+ // ── patch ─────────────────────────────────────────────────────────────────────
142
+ program
143
+ .command('patch [instruction]')
144
+ .description('Generate and optionally apply a code patch')
145
+ .option('--file <path...>', 'include these files as context')
146
+ .option('--dry', 'generate the patch but do not offer to apply')
147
+ .option('--yes', 'auto-confirm patch application')
148
+ .action(async (instruction, cmdOpts) => {
149
+ const g = globalOpts();
150
+ const { runPatch } = await import('./commands/patch.js');
151
+ await runPatch(instruction, {
152
+ profile: g.profile,
153
+ provider: g.provider,
154
+ model: g.model,
155
+ baseUrl: g.baseUrl,
156
+ file: cmdOpts['file'],
157
+ dry: cmdOpts['dry'],
158
+ yes: cmdOpts['yes'],
159
+ });
160
+ });
161
+ // ── auth ──────────────────────────────────────────────────────────────────────
162
+ const auth = program.command('auth').description('Manage authentication credentials');
163
+ auth
164
+ .command('login')
165
+ .description('Validate credentials for the current provider')
166
+ .action(async () => {
167
+ const g = globalOpts();
168
+ const { runAuthLogin } = await import('./commands/auth.js');
169
+ await runAuthLogin({ profile: g.profile, provider: g.provider, model: g.model, baseUrl: g.baseUrl });
170
+ });
171
+ auth
172
+ .command('logout')
173
+ .description('Remove stored credentials for the current provider')
174
+ .action(async () => {
175
+ const g = globalOpts();
176
+ const { runAuthLogout } = await import('./commands/auth.js');
177
+ await runAuthLogout({ profile: g.profile, provider: g.provider });
178
+ });
179
+ // ── config ────────────────────────────────────────────────────────────────────
180
+ const config = program.command('config').description('Manage Jam configuration');
181
+ config
182
+ .command('show')
183
+ .description('Show merged configuration')
184
+ .action(async () => {
185
+ const g = globalOpts();
186
+ const { runConfigShow } = await import('./commands/config.js');
187
+ await runConfigShow({ profile: g.profile });
188
+ });
189
+ config
190
+ .command('init')
191
+ .description('Initialize a config file')
192
+ .option('--global', 'write to user config (~/.config/jam/config.json)')
193
+ .action(async (opts) => {
194
+ const { runConfigInit } = await import('./commands/config.js');
195
+ await runConfigInit({ global: opts.global });
196
+ });
197
+ // ── models ────────────────────────────────────────────────────────────────────
198
+ const models = program.command('models').description('Model management');
199
+ models
200
+ .command('list')
201
+ .description('List available models for the current provider')
202
+ .action(async () => {
203
+ const g = globalOpts();
204
+ const { runModelsList } = await import('./commands/models.js');
205
+ await runModelsList({ profile: g.profile, provider: g.provider, baseUrl: g.baseUrl });
206
+ });
207
+ // ── history ───────────────────────────────────────────────────────────────────
208
+ const history = program.command('history').description('Manage chat session history');
209
+ history
210
+ .command('list')
211
+ .description('List all saved chat sessions')
212
+ .action(async () => {
213
+ const { runHistoryList } = await import('./commands/history.js');
214
+ await runHistoryList();
215
+ });
216
+ history
217
+ .command('show <sessionId>')
218
+ .description('Show messages in a chat session')
219
+ .action(async (sessionId) => {
220
+ const { runHistoryShow } = await import('./commands/history.js');
221
+ await runHistoryShow(sessionId);
222
+ });
223
+ // ── completion ────────────────────────────────────────────────────────────────
224
+ const completion = program.command('completion').description('Shell completion scripts');
225
+ completion
226
+ .command('install')
227
+ .description('Print shell completion script and installation instructions')
228
+ .option('--shell <shell>', 'target shell: bash or zsh (auto-detected if omitted)')
229
+ .action(async (opts) => {
230
+ const { runCompletionInstall } = await import('./commands/completion.js');
231
+ runCompletionInstall({ shell: opts.shell });
232
+ });
233
+ // ── doctor ────────────────────────────────────────────────────────────────────
234
+ program
235
+ .command('doctor')
236
+ .description('Run system diagnostics')
237
+ .action(async () => {
238
+ const g = globalOpts();
239
+ const { runDoctor } = await import('./commands/doctor.js');
240
+ await runDoctor({ profile: g.profile, provider: g.provider, baseUrl: g.baseUrl });
241
+ });
242
+ // ── Default action (no subcommand): print banner then help ──────────────────
243
+ if (process.argv.slice(2).length === 0) {
244
+ const noColor = process.argv.includes('--no-color');
245
+ printLogo(noColor);
246
+ program.help();
247
+ }
248
+ program.parse();
249
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,32 @@
1
+ export interface Message {
2
+ role: 'system' | 'user' | 'assistant';
3
+ content: string;
4
+ }
5
+ export interface TokenUsage {
6
+ promptTokens: number;
7
+ completionTokens: number;
8
+ totalTokens: number;
9
+ }
10
+ export interface StreamChunk {
11
+ delta: string;
12
+ done: boolean;
13
+ usage?: TokenUsage;
14
+ }
15
+ export interface CompletionRequest {
16
+ messages: Message[];
17
+ model?: string;
18
+ temperature?: number;
19
+ maxTokens?: number;
20
+ systemPrompt?: string;
21
+ }
22
+ export interface ProviderInfo {
23
+ name: string;
24
+ supportsStreaming: boolean;
25
+ }
26
+ export interface ProviderAdapter {
27
+ info: ProviderInfo;
28
+ validateCredentials(): Promise<void>;
29
+ streamCompletion(request: CompletionRequest): AsyncIterable<StreamChunk>;
30
+ listModels(): Promise<string[]>;
31
+ }
32
+ //# sourceMappingURL=base.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"base.d.ts","sourceRoot":"","sources":["../../src/providers/base.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,OAAO;IACtB,IAAI,EAAE,QAAQ,GAAG,MAAM,GAAG,WAAW,CAAC;IACtC,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,UAAU;IACzB,YAAY,EAAE,MAAM,CAAC;IACrB,gBAAgB,EAAE,MAAM,CAAC;IACzB,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,WAAW;IAC1B,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,OAAO,CAAC;IACd,KAAK,CAAC,EAAE,UAAU,CAAC;CACpB;AAED,MAAM,WAAW,iBAAiB;IAChC,QAAQ,EAAE,OAAO,EAAE,CAAC;IACpB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,iBAAiB,EAAE,OAAO,CAAC;CAC5B;AAED,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,YAAY,CAAC;IACnB,mBAAmB,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACrC,gBAAgB,CAAC,OAAO,EAAE,iBAAiB,GAAG,aAAa,CAAC,WAAW,CAAC,CAAC;IACzE,UAAU,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;CACjC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=base.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"base.js","sourceRoot":"","sources":["../../src/providers/base.ts"],"names":[],"mappings":""}
@@ -0,0 +1,4 @@
1
+ import type { ProviderAdapter } from './base.js';
2
+ import type { Profile } from '../config/schema.js';
3
+ export declare function createProvider(profile: Profile): Promise<ProviderAdapter>;
4
+ //# sourceMappingURL=factory.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"factory.d.ts","sourceRoot":"","sources":["../../src/providers/factory.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AACjD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAC;AAGnD,wBAAsB,cAAc,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,eAAe,CAAC,CAe/E"}
@@ -0,0 +1,13 @@
1
+ import { JamError } from '../utils/errors.js';
2
+ export async function createProvider(profile) {
3
+ const provider = profile.provider;
4
+ if (provider === 'ollama') {
5
+ const { OllamaAdapter } = await import('./ollama.js');
6
+ return new OllamaAdapter({
7
+ baseUrl: profile.baseUrl,
8
+ model: profile.model,
9
+ });
10
+ }
11
+ throw new JamError(`Unknown provider: "${provider}". Supported providers: ollama`, 'CONFIG_INVALID');
12
+ }
13
+ //# sourceMappingURL=factory.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"factory.js","sourceRoot":"","sources":["../../src/providers/factory.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAE9C,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,OAAgB;IACnD,MAAM,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAC;IAElC,IAAI,QAAQ,KAAK,QAAQ,EAAE,CAAC;QAC1B,MAAM,EAAE,aAAa,EAAE,GAAG,MAAM,MAAM,CAAC,aAAa,CAAC,CAAC;QACtD,OAAO,IAAI,aAAa,CAAC;YACvB,OAAO,EAAE,OAAO,CAAC,OAAO;YACxB,KAAK,EAAE,OAAO,CAAC,KAAK;SACrB,CAAC,CAAC;IACL,CAAC;IAED,MAAM,IAAI,QAAQ,CAChB,sBAAsB,QAAQ,gCAAgC,EAC9D,gBAAgB,CACjB,CAAC;AACJ,CAAC"}
@@ -0,0 +1,14 @@
1
+ import type { ProviderAdapter, ProviderInfo, CompletionRequest, StreamChunk } from './base.js';
2
+ export declare class OllamaAdapter implements ProviderAdapter {
3
+ readonly info: ProviderInfo;
4
+ private readonly baseUrl;
5
+ private readonly model;
6
+ constructor(options?: {
7
+ baseUrl?: string;
8
+ model?: string;
9
+ });
10
+ listModels(): Promise<string[]>;
11
+ validateCredentials(): Promise<void>;
12
+ streamCompletion(request: CompletionRequest): AsyncIterable<StreamChunk>;
13
+ }
14
+ //# sourceMappingURL=ollama.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ollama.d.ts","sourceRoot":"","sources":["../../src/providers/ollama.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,YAAY,EAAE,iBAAiB,EAAE,WAAW,EAAW,MAAM,WAAW,CAAC;AAmCxG,qBAAa,aAAc,YAAW,eAAe;IACnD,QAAQ,CAAC,IAAI,EAAE,YAAY,CAGzB;IAEF,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAS;gBAEnB,OAAO,GAAE;QAAE,OAAO,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAO;IAKxD,UAAU,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;IA8B/B,mBAAmB,IAAI,OAAO,CAAC,IAAI,CAAC;IAsBnC,gBAAgB,CAAC,OAAO,EAAE,iBAAiB,GAAG,aAAa,CAAC,WAAW,CAAC;CAoHhF"}
@@ -0,0 +1,152 @@
1
+ import { JamError } from '../utils/errors.js';
2
+ const DEFAULT_BASE_URL = 'http://localhost:11434';
3
+ function toOllamaMessages(messages) {
4
+ return messages.map((m) => ({ role: m.role, content: m.content }));
5
+ }
6
+ function parseNDJSONLine(line) {
7
+ const trimmed = line.trim();
8
+ if (!trimmed)
9
+ return null;
10
+ try {
11
+ return JSON.parse(trimmed);
12
+ }
13
+ catch {
14
+ return null;
15
+ }
16
+ }
17
+ export class OllamaAdapter {
18
+ info = {
19
+ name: 'ollama',
20
+ supportsStreaming: true,
21
+ };
22
+ baseUrl;
23
+ model;
24
+ constructor(options = {}) {
25
+ this.baseUrl = (options.baseUrl ?? DEFAULT_BASE_URL).replace(/\/$/, '');
26
+ this.model = options.model ?? 'llama3.2';
27
+ }
28
+ async listModels() {
29
+ let response;
30
+ try {
31
+ response = await fetch(`${this.baseUrl}/api/tags`, {
32
+ signal: AbortSignal.timeout(5000),
33
+ });
34
+ }
35
+ catch (err) {
36
+ throw new JamError(`Cannot reach Ollama at ${this.baseUrl}. Start Ollama with: ollama serve`, 'PROVIDER_UNAVAILABLE', { retryable: false, cause: err });
37
+ }
38
+ if (!response.ok) {
39
+ throw new JamError(`Ollama returned HTTP ${response.status}. Is Ollama running at ${this.baseUrl}?`, 'PROVIDER_UNAVAILABLE', { retryable: false });
40
+ }
41
+ const data = (await response.json());
42
+ return (data.models ?? []).map((m) => m.name);
43
+ }
44
+ async validateCredentials() {
45
+ try {
46
+ const response = await fetch(`${this.baseUrl}/api/tags`, {
47
+ signal: AbortSignal.timeout(5000),
48
+ });
49
+ if (!response.ok) {
50
+ throw new JamError(`Ollama returned HTTP ${response.status}. Is Ollama running at ${this.baseUrl}?`, 'PROVIDER_UNAVAILABLE', { retryable: false });
51
+ }
52
+ }
53
+ catch (err) {
54
+ if (JamError.isJamError(err))
55
+ throw err;
56
+ throw new JamError(`Cannot reach Ollama at ${this.baseUrl}. Start Ollama with: ollama serve`, 'PROVIDER_UNAVAILABLE', { retryable: false, cause: err });
57
+ }
58
+ }
59
+ async *streamCompletion(request) {
60
+ const messages = [];
61
+ const systemPrompt = request.systemPrompt;
62
+ if (systemPrompt) {
63
+ messages.push({ role: 'system', content: systemPrompt });
64
+ }
65
+ messages.push(...toOllamaMessages(request.messages));
66
+ const body = {
67
+ model: request.model ?? this.model,
68
+ messages,
69
+ stream: true,
70
+ options: {
71
+ ...(request.temperature !== undefined ? { temperature: request.temperature } : {}),
72
+ ...(request.maxTokens !== undefined ? { num_predict: request.maxTokens } : {}),
73
+ },
74
+ };
75
+ let response;
76
+ try {
77
+ response = await fetch(`${this.baseUrl}/api/chat`, {
78
+ method: 'POST',
79
+ headers: { 'Content-Type': 'application/json' },
80
+ body: JSON.stringify(body),
81
+ signal: AbortSignal.timeout(120_000),
82
+ });
83
+ }
84
+ catch (err) {
85
+ throw new JamError(`Failed to connect to Ollama at ${this.baseUrl}`, 'PROVIDER_UNAVAILABLE', { retryable: true, cause: err });
86
+ }
87
+ if (!response.ok) {
88
+ const errorText = await response.text().catch(() => '');
89
+ if (response.status === 404) {
90
+ throw new JamError(`Model not found: ${request.model ?? this.model}. Pull it with: ollama pull ${request.model ?? this.model}`, 'PROVIDER_MODEL_NOT_FOUND', { retryable: false, statusCode: response.status });
91
+ }
92
+ if (response.status === 429) {
93
+ throw new JamError('Ollama rate limited. Try again shortly.', 'PROVIDER_RATE_LIMITED', { retryable: true, statusCode: response.status });
94
+ }
95
+ throw new JamError(`Ollama error ${response.status}: ${errorText}`, 'PROVIDER_STREAM_ERROR', { retryable: false, statusCode: response.status });
96
+ }
97
+ if (!response.body) {
98
+ throw new JamError('Ollama returned empty response body', 'PROVIDER_STREAM_ERROR', {
99
+ retryable: true,
100
+ });
101
+ }
102
+ const decoder = new TextDecoder();
103
+ let buffer = '';
104
+ for await (const rawChunk of response.body) {
105
+ buffer += decoder.decode(rawChunk, { stream: true });
106
+ const lines = buffer.split('\n');
107
+ buffer = lines.pop() ?? '';
108
+ for (const line of lines) {
109
+ const parsed = parseNDJSONLine(line);
110
+ if (!parsed)
111
+ continue;
112
+ if (!parsed.done) {
113
+ yield {
114
+ delta: parsed.message.content,
115
+ done: false,
116
+ };
117
+ }
118
+ else {
119
+ const promptTokens = parsed.prompt_eval_count ?? 0;
120
+ const completionTokens = parsed.eval_count ?? 0;
121
+ yield {
122
+ delta: '',
123
+ done: true,
124
+ usage: {
125
+ promptTokens,
126
+ completionTokens,
127
+ totalTokens: promptTokens + completionTokens,
128
+ },
129
+ };
130
+ }
131
+ }
132
+ }
133
+ // Flush any remaining buffer
134
+ if (buffer.trim()) {
135
+ const parsed = parseNDJSONLine(buffer);
136
+ if (parsed?.done) {
137
+ const promptTokens = parsed.prompt_eval_count ?? 0;
138
+ const completionTokens = parsed.eval_count ?? 0;
139
+ yield {
140
+ delta: '',
141
+ done: true,
142
+ usage: {
143
+ promptTokens,
144
+ completionTokens,
145
+ totalTokens: promptTokens + completionTokens,
146
+ },
147
+ };
148
+ }
149
+ }
150
+ }
151
+ }
152
+ //# sourceMappingURL=ollama.js.map