@ariacode/cli 0.1.0 → 0.2.2

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 (82) hide show
  1. package/README.md +190 -5
  2. package/dist/actions/db-ask.d.ts +16 -0
  3. package/dist/actions/db-ask.js +130 -0
  4. package/dist/actions/db-ask.js.map +1 -0
  5. package/dist/actions/db-explain.d.ts +16 -0
  6. package/dist/actions/db-explain.js +123 -0
  7. package/dist/actions/db-explain.js.map +1 -0
  8. package/dist/actions/db-migrate.d.ts +17 -0
  9. package/dist/actions/db-migrate.js +124 -0
  10. package/dist/actions/db-migrate.js.map +1 -0
  11. package/dist/actions/db-schema.d.ts +11 -0
  12. package/dist/actions/db-schema.js +38 -0
  13. package/dist/actions/db-schema.js.map +1 -0
  14. package/dist/actions/upgrade-deps.d.ts +18 -0
  15. package/dist/actions/upgrade-deps.js +227 -0
  16. package/dist/actions/upgrade-deps.js.map +1 -0
  17. package/dist/actions/upgrade-prisma.d.ts +16 -0
  18. package/dist/actions/upgrade-prisma.js +177 -0
  19. package/dist/actions/upgrade-prisma.js.map +1 -0
  20. package/dist/actions.d.ts +20 -0
  21. package/dist/actions.js +105 -36
  22. package/dist/actions.js.map +1 -1
  23. package/dist/agent.js +28 -9
  24. package/dist/agent.js.map +1 -1
  25. package/dist/cli.js +102 -0
  26. package/dist/cli.js.map +1 -1
  27. package/dist/config.d.ts +16 -0
  28. package/dist/config.js +39 -0
  29. package/dist/config.js.map +1 -1
  30. package/dist/db/client-usage.d.ts +19 -0
  31. package/dist/db/client-usage.js +107 -0
  32. package/dist/db/client-usage.js.map +1 -0
  33. package/dist/db/migrate.d.ts +26 -0
  34. package/dist/db/migrate.js +59 -0
  35. package/dist/db/migrate.js.map +1 -0
  36. package/dist/db/schema.d.ts +106 -0
  37. package/dist/db/schema.js +275 -0
  38. package/dist/db/schema.js.map +1 -0
  39. package/dist/db/summary.d.ts +12 -0
  40. package/dist/db/summary.js +133 -0
  41. package/dist/db/summary.js.map +1 -0
  42. package/dist/fs-helpers.d.ts +19 -0
  43. package/dist/fs-helpers.js +92 -0
  44. package/dist/fs-helpers.js.map +1 -0
  45. package/dist/parser.d.ts +11 -0
  46. package/dist/parser.js +102 -0
  47. package/dist/parser.js.map +1 -1
  48. package/dist/prompt-loader.d.ts +9 -0
  49. package/dist/prompt-loader.js +26 -0
  50. package/dist/prompt-loader.js.map +1 -0
  51. package/dist/prompts/db_ask.md +39 -0
  52. package/dist/prompts/db_explain.md +43 -0
  53. package/dist/prompts/db_migrate.md +48 -0
  54. package/dist/prompts/upgrade_deps.md +23 -0
  55. package/dist/prompts/upgrade_prisma.md +28 -0
  56. package/dist/provider.d.ts +9 -2
  57. package/dist/provider.js +12 -39
  58. package/dist/provider.js.map +1 -1
  59. package/dist/storage.d.ts +11 -0
  60. package/dist/storage.js +36 -4
  61. package/dist/storage.js.map +1 -1
  62. package/dist/tools.d.ts +26 -0
  63. package/dist/tools.js +256 -8
  64. package/dist/tools.js.map +1 -1
  65. package/dist/upgrade/changelog.d.ts +21 -0
  66. package/dist/upgrade/changelog.js +62 -0
  67. package/dist/upgrade/changelog.js.map +1 -0
  68. package/dist/upgrade/classifier.d.ts +25 -0
  69. package/dist/upgrade/classifier.js +78 -0
  70. package/dist/upgrade/classifier.js.map +1 -0
  71. package/dist/upgrade/outdated.d.ts +17 -0
  72. package/dist/upgrade/outdated.js +138 -0
  73. package/dist/upgrade/outdated.js.map +1 -0
  74. package/dist/upgrade/prisma-upgrade.d.ts +20 -0
  75. package/dist/upgrade/prisma-upgrade.js +66 -0
  76. package/dist/upgrade/prisma-upgrade.js.map +1 -0
  77. package/package.json +7 -4
  78. package/dist/prompts/prompts/ask.md +0 -20
  79. package/dist/prompts/prompts/explore.md +0 -38
  80. package/dist/prompts/prompts/patch.md +0 -27
  81. package/dist/prompts/prompts/plan.md +0 -41
  82. package/dist/prompts/prompts/review.md +0 -33
@@ -0,0 +1 @@
1
+ {"version":3,"file":"upgrade-prisma.js","sourceRoot":"","sources":["../../src/actions/upgrade-prisma.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAElC,OAAO,EAAE,SAAS,EAAe,MAAM,cAAc,CAAC;AACtD,OAAO,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAC/C,OAAO,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AACpD,OAAO,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAChD,OAAO,EACL,kBAAkB,EAClB,sBAAsB,EACtB,mBAAmB,EACnB,UAAU,EACV,WAAW,GACZ,MAAM,eAAe,CAAC;AACvB,OAAO,EACL,MAAM,EACN,IAAI,EACJ,OAAO,EACP,IAAI,EACJ,KAAK,IAAI,OAAO,EAChB,IAAI,EACJ,GAAG,EACH,OAAO,EACP,qBAAqB,EACrB,aAAa,GACd,MAAM,UAAU,CAAC;AAClB,OAAO,EAAE,oBAAoB,EAAE,MAAM,8BAA8B,CAAC;AACpE,OAAO,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AACjE,OAAO,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AAczD,MAAM,CAAC,KAAK,UAAU,gBAAgB,CAAC,OAA6B;IAClE,MAAM,WAAW,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,WAAW,IAAI,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC;IACvE,MAAM,MAAM,GAAG,SAAS,CAAC,WAAW,EAAE,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE,QAAQ,EAAE,OAAO,CAAC,QAAQ,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE,CAAC,CAAC;IAClH,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,CAAC,EAAE,CAAC,KAAK,IAAI,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC;IAEnE,MAAM,OAAO,GAAG,iBAAiB,CAAC,WAAW,CAAC,CAAC;IAC/C,MAAM,EAAE,GAAG,OAAO,CAAC,cAAc,IAAI,KAAK,CAAC;IAE3C,iCAAiC;IACjC,MAAM,WAAW,GAAG,MAAM,oBAAoB,CAAC,WAAW,CAAC,CAAC;IAC5D,IAAI,CAAC,WAAW,CAAC,SAAS,EAAE,CAAC;QAC3B,OAAO,CAAC,qCAAqC,CAAC,CAAC;QAC/C,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,MAAM,OAAO,GAAG,WAAW,CAAC,aAAa,IAAI,WAAW,CAAC,aAAa,CAAC;IACvE,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,OAAO,CAAC,8DAA8D,CAAC,CAAC;QACxE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,0BAA0B;IAC1B,MAAM,OAAO,GAAG,aAAa,CAAC,mCAAmC,CAAC,CAAC;IACnE,OAAO,CAAC,KAAK,EAAE,CAAC;IAEhB,IAAI,CAAC,WAAW,CAAC,aAAa,EAAE,CAAC;QAC/B,OAAO,CAAC,IAAI,CAAC,uCAAuC,CAAC,CAAC;QACtD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,IAAI,OAAO,KAAK,WAAW,CAAC,aAAa,EAAE,CAAC;QAC1C,OAAO,CAAC,OAAO,CAAC,yBAAyB,OAAO,GAAG,CAAC,CAAC;QACrD,OAAO;IACT,CAAC;IAED,OAAO,CAAC,OAAO,CACb,6BAA6B,OAAO,MAAM,WAAW,CAAC,aAAa,KAAK,WAAW,CAAC,IAAI,GAAG,CAC5F,CAAC;IAEF,wDAAwD;IACxD,MAAM,aAAa,GAAG,CAAC,cAAc,CAAC,CAAC;IACvC,IAAI,WAAW,CAAC,IAAI,KAAK,OAAO,IAAI,OAAO,CAAC,gBAAgB,EAAE,CAAC;QAC7D,aAAa,CAAC,IAAI,CAAC,OAAO,CAAC,gBAAgB,CAAC,CAAC;QAC7C,MAAM,yBAAyB,CAC7B,OAAO,EACP,WAAW,CAAC,aAAa,EACzB,WAAW,EACX,MAAM,CACP,CAAC;IACJ,CAAC;IAED,oBAAoB;IACpB,IAAI,CAAC,EAAE,CAAC,CAAC;IACT,IAAI,CAAC,GAAG,CAAC,uBAAuB,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,oBAAoB,CAAC,CAAC,CAAC;IAE/E,mCAAmC;IACnC,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;QACnB,IAAI,CAAC,mDAAmD,CAAC,CAAC;QAC1D,OAAO;IACT,CAAC;IAED,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC;QACjB,MAAM,EAAE,GAAG,MAAM,OAAO,CAAC,uCAAuC,CAAC,CAAC;QAClE,IAAI,CAAC,EAAE;YAAE,MAAM,IAAI,qBAAqB,EAAE,CAAC;IAC7C,CAAC;IAED,wCAAwC;IACxC,kBAAkB,CAAC,WAAW,EAAE,WAAW,CAAC,aAAa,CAAC,CAAC;IAE3D,iDAAiD;IACjD,MAAM,EAAE,GAAG,kBAAkB,EAAE,CAAC;IAChC,MAAM,SAAS,GAAG,sBAAsB,CAAC,EAAE,EAAE;QAC3C,SAAS,EAAE,OAAO,CAAC,OAAO;QAC1B,OAAO,EAAE,gBAAgB;QACzB,WAAW;QACX,QAAQ,EAAE,MAAM,CAAC,QAAQ,CAAC,OAAO;QACjC,KAAK,EAAE,MAAM,CAAC,QAAQ,CAAC,KAAK;KAC7B,CAAC,CAAC;IACH,WAAW,CAAC,EAAE,EAAE,SAAS,EAAE;QACzB,MAAM,EAAE,gBAAgB;QACxB,aAAa;QACb,SAAS,EAAE,MAAM;QACjB,UAAU,EAAE,IAAI;QAChB,aAAa,EAAE,CAAC,8BAA8B,EAAE,GAAG,EAAE,UAAU,CAAC;KACjE,CAAC,CAAC;IACH,mBAAmB,CAAC,EAAE,EAAE,SAAS,EAAE,WAAW,CAAC,CAAC;IAEhD,sBAAsB;IACtB,MAAM,SAAS,GAAG,EAAE,KAAK,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC;IAC5C,MAAM,UAAU,GAAG,iDAAiD,WAAW,CAAC,aAAa,EAAE,CAAC;IAEhG,IAAI,CAAC,EAAE,CAAC,CAAC;IACT,OAAO,CAAC,0CAA0C,CAAC,CAAC;IACpD,IAAI,WAAW,CAAC,aAAa,EAAE,CAAC;QAC9B,IAAI,CAAC,eAAe,WAAW,CAAC,aAAa,MAAM,WAAW,CAAC,aAAa,EAAE,CAAC,CAAC;IAClF,CAAC;IACD,IAAI,WAAW,CAAC,aAAa,EAAE,CAAC;QAC9B,IAAI,CAAC,uBAAuB,WAAW,CAAC,aAAa,MAAM,WAAW,CAAC,aAAa,EAAE,CAAC,CAAC;IAC1F,CAAC;IACD,IAAI,CAAC,EAAE,CAAC,CAAC;IACT,IAAI,CAAC,4BAA4B,CAAC,CAAC;IACnC,IAAI,CAAC,EAAE,CAAC,CAAC;IACT,IAAI,CAAC,kCAAkC,CAAC,CAAC;IACzC,IAAI,CAAC,QAAQ,EAAE,UAAU,CAAC,CAAC;IAC3B,IAAI,CAAC,EAAE,CAAC,CAAC;IACT,IAAI,CAAC,8BAA8B,CAAC,CAAC;IACrC,IAAI,CAAC,QAAQ,SAAS,kBAAkB,CAAC,CAAC;IAC1C,IAAI,CAAC,EAAE,CAAC,CAAC;IACT,IAAI,CAAC,6BAA6B,CAAC,CAAC;IACpC,IAAI,CAAC,QAAQ,UAAU,EAAE,CAAC,CAAC;IAC3B,IAAI,CAAC,EAAE,CAAC,CAAC;IACT,IAAI,CAAC,yBAAyB,CAAC,CAAC;IAChC,IAAI,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;IACxB,IAAI,CAAC,EAAE,CAAC,CAAC;IACT,IAAI,CAAC,qCAAqC,CAAC,CAAC;IAC5C,IAAI,CAAC,0CAA0C,CAAC,CAAC;AACnD,CAAC;AAED,8EAA8E;AAC9E,UAAU;AACV,8EAA8E;AAE9E;;GAEG;AACH,SAAS,kBAAkB,CAAC,WAAmB,EAAE,aAAqB;IACpE,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,cAAc,CAAC,CAAC;IACvD,MAAM,GAAG,GAAG,YAAY,CAAC,OAAO,CAAwB,CAAC;IAEzD,MAAM,aAAa,GAAG,CAAC,OAA2C,EAAE,IAAY,EAAE,EAAE;QAClF,IAAI,CAAC,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC,KAAK,SAAS;YAAE,OAAO;QACpD,MAAM,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;QAC/B,MAAM,MAAM,GAAG,QAAQ,CAAC,KAAK,CAAC,YAAY,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC;QACxD,OAAO,CAAC,IAAI,CAAC,GAAG,GAAG,MAAM,GAAG,aAAa,EAAE,CAAC;IAC9C,CAAC,CAAC;IAEF,aAAa,CAAC,GAAG,CAAC,YAAY,EAAE,QAAQ,CAAC,CAAC;IAC1C,aAAa,CAAC,GAAG,CAAC,YAAY,EAAE,gBAAgB,CAAC,CAAC;IAClD,aAAa,CAAC,GAAG,CAAC,eAAe,EAAE,QAAQ,CAAC,CAAC;IAC7C,aAAa,CAAC,GAAG,CAAC,eAAe,EAAE,gBAAgB,CAAC,CAAC;IAErD,eAAe,CAAC,OAAO,EAAE,IAAI,CAAC,SAAS,CAAC,GAAG,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;AAChE,CAAC;AAED;;;GAGG;AACH,KAAK,UAAU,yBAAyB,CACtC,cAAsB,EACtB,aAAqB,EACrB,WAAmB,EACnB,MAAc;IAEd,MAAM,UAAU,GAAG,iBAAiB,CAAC,WAAW,CAAC,CAAC;IAClD,MAAM,aAAa,GAAG,UAAU;QAC9B,CAAC,CAAC,WAAW,UAAU,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,eAAe,UAAU,CAAC,kBAAkB,IAAI,SAAS,EAAE;QACvH,CAAC,CAAC,wBAAwB,CAAC;IAE7B,MAAM,QAAQ,GAAG,kBAAkB,CACjC,gBAAgB,EAChB,0GAA0G,CAC3G,CAAC;IAEF,MAAM,YAAY,GAAG,QAAQ;SAC1B,OAAO,CAAC,4BAA4B,EAAE,cAAc,CAAC;SACrD,OAAO,CAAC,2BAA2B,EAAE,aAAa,CAAC;SACnD,OAAO,CAAC,2BAA2B,EAAE,aAAa,CAAC,CAAC;IAEvD,IAAI,CAAC,EAAE,CAAC,CAAC;IACT,IAAI,CAAC,IAAI,CAAC,0BAA0B,CAAC,CAAC,CAAC;IAEvC,IAAI,CAAC;QACH,MAAM,QAAQ,GAAG,cAAc,CAAC,MAAM,CAAC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC,QAAQ,CAAC,CAAC;QAC1E,MAAM,EAAE,GAAG,kBAAkB,EAAE,CAAC;QAChC,MAAM,SAAS,GAAG,sBAAsB,CAAC,EAAE,EAAE;YAC3C,OAAO,EAAE,yBAAyB;YAClC,WAAW;YACX,QAAQ,EAAE,MAAM,CAAC,QAAQ,CAAC,OAAO;YACjC,KAAK,EAAE,MAAM,CAAC,QAAQ,CAAC,KAAK;SAC7B,CAAC,CAAC;QAEH,UAAU,CAAC,EAAE,EAAE,SAAS,EAAE,QAAQ,EAAE,YAAY,CAAC,CAAC;QAElD,mEAAmE;QACnE,MAAM,QAAQ,GAAG,MAAM,QAAQ,CAAC,IAAI,CAClC;YACE,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,YAAY,EAAE;YACzC;gBACE,IAAI,EAAE,MAAM;gBACZ,OAAO,EAAE,mCAAmC,cAAc,OAAO,aAAa,kCAAkC;aACjH;SACF,EACD,EAAE,EACF,EAAE,KAAK,EAAE,MAAM,CAAC,QAAQ,CAAC,KAAK,EAAE,SAAS,EAAE,MAAM,CAAC,QAAQ,CAAC,SAAS,EAAE,CACvE,CAAC;QAEF,IAAI,QAAQ,CAAC,OAAO,EAAE,CAAC;YACrB,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;QACzB,CAAC;QAED,UAAU,CAAC,EAAE,EAAE,SAAS,EAAE,WAAW,EAAE,QAAQ,CAAC,OAAO,CAAC,CAAC;QACzD,mBAAmB,CAAC,EAAE,EAAE,SAAS,EAAE,WAAW,CAAC,CAAC;IAClD,CAAC;IAAC,MAAM,CAAC;QACP,IAAI,CAAC,2EAA2E,CAAC,CAAC;IACpF,CAAC;AACH,CAAC"}
package/dist/actions.d.ts CHANGED
@@ -22,6 +22,10 @@ export interface AskOptions {
22
22
  quiet?: boolean;
23
23
  /** Project root (defaults to process.cwd()) */
24
24
  projectRoot?: string;
25
+ /** Override provider (v0.2.2) */
26
+ provider?: string;
27
+ /** Override model (v0.2.2) */
28
+ model?: string;
25
29
  }
26
30
  /**
27
31
  * Execute the ask command.
@@ -52,6 +56,10 @@ export interface PlanOptions {
52
56
  quiet?: boolean;
53
57
  /** Project root (defaults to process.cwd()) */
54
58
  projectRoot?: string;
59
+ /** Override provider (v0.2.2) */
60
+ provider?: string;
61
+ /** Override model (v0.2.2) */
62
+ model?: string;
55
63
  }
56
64
  /**
57
65
  * Execute the plan command.
@@ -85,6 +93,10 @@ export interface PatchOptions {
85
93
  quiet?: boolean;
86
94
  /** Project root (defaults to process.cwd()) */
87
95
  projectRoot?: string;
96
+ /** Override provider (v0.2.2) */
97
+ provider?: string;
98
+ /** Override model (v0.2.2) */
99
+ model?: string;
88
100
  }
89
101
  /**
90
102
  * Execute the patch command.
@@ -121,6 +133,10 @@ export interface ReviewOptions {
121
133
  quiet?: boolean;
122
134
  /** Project root (defaults to process.cwd()) */
123
135
  projectRoot?: string;
136
+ /** Override provider (v0.2.2) */
137
+ provider?: string;
138
+ /** Override model (v0.2.2) */
139
+ model?: string;
124
140
  }
125
141
  /**
126
142
  * Structured review returned by the provider.
@@ -163,6 +179,10 @@ export interface ExploreOptions {
163
179
  quiet?: boolean;
164
180
  /** Project root (defaults to process.cwd()) */
165
181
  projectRoot?: string;
182
+ /** Override provider (v0.2.2) */
183
+ provider?: string;
184
+ /** Override model (v0.2.2) */
185
+ model?: string;
166
186
  }
167
187
  /**
168
188
  * Execute the explore command.
package/dist/actions.js CHANGED
@@ -24,6 +24,7 @@ import { agentLoop, UserCancelledError } from "./agent.js";
24
24
  import prompts from "prompts";
25
25
  import { initUI, info, print, error as uiError, bold, yellow, green, dim, cyan, red, renderTable, generateAndRenderDiff, confirm, ConfirmCancelledError, } from "./ui.js";
26
26
  import { loadConfig, validateConfig } from "./config.js";
27
+ import { getShellRcPath } from "./fs-helpers.js";
27
28
  const __dirname = dirname(fileURLToPath(import.meta.url));
28
29
  // ---------------------------------------------------------------------------
29
30
  // Provider resolution with interactive setup
@@ -47,6 +48,20 @@ const DEFAULT_MODELS = {
47
48
  ollama: "llama3",
48
49
  openrouter: "anthropic/claude-sonnet-4-6",
49
50
  };
51
+ /**
52
+ * Resolve the effective model for the current provider config.
53
+ * Per-provider model overrides take precedence over the global model setting.
54
+ */
55
+ function resolveModel(config) {
56
+ const provider = config.provider.default;
57
+ if (provider === "anthropic" && config.provider.anthropic?.model) {
58
+ return config.provider.anthropic.model;
59
+ }
60
+ if (provider === "openrouter" && config.provider.openrouter?.model) {
61
+ return config.provider.openrouter.model;
62
+ }
63
+ return config.provider.model;
64
+ }
50
65
  /**
51
66
  * Check if the given provider has its API key available.
52
67
  */
@@ -68,7 +83,7 @@ function isProviderReady(providerName) {
68
83
  async function resolveProvider(config) {
69
84
  // 1. Try the configured provider first
70
85
  if (isProviderReady(config.provider.default)) {
71
- return createProvider(config.provider.default);
86
+ return createProvider(config.provider.default, config.provider);
72
87
  }
73
88
  // 2. Check if any other provider is already configured via env
74
89
  for (const [name, envKey] of Object.entries(PROVIDER_ENV_KEYS)) {
@@ -78,7 +93,7 @@ async function resolveProvider(config) {
78
93
  info(dim(`${config.provider.default} not configured, falling back to ${name}`));
79
94
  config.provider.default = name;
80
95
  config.provider.model = DEFAULT_MODELS[name] ?? config.provider.model;
81
- return createProvider(name);
96
+ return createProvider(name, config.provider);
82
97
  }
83
98
  }
84
99
  // 3. No provider ready — interactive setup
@@ -145,30 +160,33 @@ async function resolveProvider(config) {
145
160
  const { saveKey } = await prompts({
146
161
  type: "confirm",
147
162
  name: "saveKey",
148
- message: `Save ${envKey} to ~/.zshrc for future sessions?`,
163
+ message: `Save ${envKey} to shell profile for future sessions?`,
149
164
  initial: true,
150
165
  }, {
151
166
  onCancel: () => { },
152
167
  });
153
168
  if (saveKey) {
154
- const shellRc = path.join(os.homedir(), ".zshrc");
155
- const exportLine = `\nexport ${envKey}="${apiKey}"\n`;
169
+ const shellRc = getShellRcPath();
170
+ const shellRcName = path.basename(shellRc);
171
+ // Escape double quotes, dollar signs, and backticks in the API key to prevent shell injection
172
+ const escapedKey = apiKey.replace(/\\/g, '\\\\').replace(/"/g, '\\"').replace(/\$/g, '\\$').replace(/`/g, '\\`');
173
+ const exportLine = `\nexport ${envKey}="${escapedKey}"\n`;
156
174
  try {
157
175
  const existing = existsSync(shellRc) ? readFileSync(shellRc, "utf-8") : "";
158
176
  if (!existing.includes(envKey)) {
159
177
  writeFileSync(shellRc, existing + exportLine, "utf-8");
160
- info(green(`✓ Added ${envKey} to ~/.zshrc`));
161
- info(dim(" Run `source ~/.zshrc` or open a new terminal to apply."));
178
+ info(green(`✓ Added ${envKey} to ~/${shellRcName}`));
179
+ info(dim(` Run \`source ~/${shellRcName}\` or open a new terminal to apply.`));
162
180
  }
163
181
  else {
164
- info(dim(`${envKey} already exists in ~/.zshrc, skipping.`));
182
+ info(dim(`${envKey} already exists in ~/${shellRcName}, skipping.`));
165
183
  }
166
184
  }
167
185
  catch {
168
- info(yellow(`Could not write to ~/.zshrc. Set ${envKey} manually.`));
186
+ info(yellow(`Could not write to ~/${shellRcName}. Set ${envKey} manually.`));
169
187
  }
170
188
  }
171
- return createProvider(selectedProvider);
189
+ return createProvider(selectedProvider, config.provider);
172
190
  }
173
191
  /**
174
192
  * Save the provider/model choice to ~/.aria/config.toml
@@ -338,6 +356,8 @@ export async function runAsk(options) {
338
356
  const config = getConfig(projectRoot, {
339
357
  quiet: options.quiet,
340
358
  maxTokens: options.maxTokens,
359
+ provider: options.provider,
360
+ model: options.model,
341
361
  });
342
362
  // Initialize UI with config settings
343
363
  initUI(config.ui.color, config.ui.quiet);
@@ -370,7 +390,7 @@ export async function runAsk(options) {
370
390
  command: "ask",
371
391
  projectRoot,
372
392
  provider: config.provider.default,
373
- model: config.provider.model,
393
+ model: resolveModel(config),
374
394
  });
375
395
  }
376
396
  // 3. Resolve provider (interactive setup if needed)
@@ -393,7 +413,7 @@ export async function runAsk(options) {
393
413
  projectRoot,
394
414
  sessionId,
395
415
  provider: config.provider.default,
396
- model: config.provider.model,
416
+ model: resolveModel(config),
397
417
  mode: "plan", // ask is always read-only
398
418
  dryRun: false,
399
419
  assumeYes: false,
@@ -455,6 +475,8 @@ export async function runPlan(options) {
455
475
  // 1. Load configuration (Req 10.1)
456
476
  const config = getConfig(projectRoot, {
457
477
  quiet: options.quiet,
478
+ provider: options.provider,
479
+ model: options.model,
458
480
  });
459
481
  // Initialize UI with config settings
460
482
  initUI(config.ui.color, config.ui.quiet);
@@ -487,7 +509,7 @@ export async function runPlan(options) {
487
509
  command: "plan",
488
510
  projectRoot,
489
511
  provider: config.provider.default,
490
- model: config.provider.model,
512
+ model: resolveModel(config),
491
513
  });
492
514
  }
493
515
  // 3. Resolve provider (interactive setup if needed)
@@ -510,7 +532,7 @@ export async function runPlan(options) {
510
532
  projectRoot,
511
533
  sessionId,
512
534
  provider: config.provider.default,
513
- model: config.provider.model,
535
+ model: resolveModel(config),
514
536
  mode: "plan", // plan is always read-only
515
537
  dryRun: false,
516
538
  assumeYes: false,
@@ -579,6 +601,8 @@ export async function runPatch(options) {
579
601
  // 1. Load configuration (Req 11.1)
580
602
  const config = getConfig(projectRoot, {
581
603
  quiet: options.quiet,
604
+ provider: options.provider,
605
+ model: options.model,
582
606
  });
583
607
  // Apply flag overrides to config
584
608
  if (options.dryRun)
@@ -606,7 +630,7 @@ export async function runPatch(options) {
606
630
  command: "patch",
607
631
  projectRoot,
608
632
  provider: config.provider.default,
609
- model: config.provider.model,
633
+ model: resolveModel(config),
610
634
  });
611
635
  }
612
636
  // 3. Resolve provider (interactive setup if needed)
@@ -629,7 +653,7 @@ export async function runPatch(options) {
629
653
  projectRoot,
630
654
  sessionId,
631
655
  provider: config.provider.default,
632
- model: config.provider.model,
656
+ model: resolveModel(config),
633
657
  mode: "build",
634
658
  dryRun: Boolean(options.dryRun),
635
659
  assumeYes: Boolean(options.yes),
@@ -838,6 +862,8 @@ export async function runReview(options) {
838
862
  // 1. Load configuration (Req 12.1)
839
863
  const config = getConfig(projectRoot, {
840
864
  quiet: options.quiet,
865
+ provider: options.provider,
866
+ model: options.model,
841
867
  });
842
868
  // Initialize UI with config settings
843
869
  initUI(config.ui.color, config.ui.quiet || Boolean(options.quiet));
@@ -851,7 +877,7 @@ export async function runReview(options) {
851
877
  command: "review",
852
878
  projectRoot,
853
879
  provider: config.provider.default,
854
- model: config.provider.model,
880
+ model: resolveModel(config),
855
881
  });
856
882
  // Resolve provider (interactive setup if needed)
857
883
  let provider;
@@ -873,7 +899,7 @@ export async function runReview(options) {
873
899
  projectRoot,
874
900
  sessionId,
875
901
  provider: config.provider.default,
876
- model: config.provider.model,
902
+ model: resolveModel(config),
877
903
  mode: "plan", // review is always read-only
878
904
  dryRun: false,
879
905
  assumeYes: false,
@@ -980,6 +1006,8 @@ export async function runExplore(options) {
980
1006
  // 1. Load configuration (Req 13.1)
981
1007
  const config = getConfig(projectRoot, {
982
1008
  quiet: options.quiet,
1009
+ provider: options.provider,
1010
+ model: options.model,
983
1011
  });
984
1012
  // Initialize UI with config settings
985
1013
  initUI(config.ui.color, config.ui.quiet || Boolean(options.quiet));
@@ -993,7 +1021,7 @@ export async function runExplore(options) {
993
1021
  command: "explore",
994
1022
  projectRoot,
995
1023
  provider: config.provider.default,
996
- model: config.provider.model,
1024
+ model: resolveModel(config),
997
1025
  });
998
1026
  // 3. Resolve provider (interactive setup if needed)
999
1027
  let provider;
@@ -1015,7 +1043,7 @@ export async function runExplore(options) {
1015
1043
  projectRoot,
1016
1044
  sessionId,
1017
1045
  provider: config.provider.default,
1018
- model: config.provider.model,
1046
+ model: resolveModel(config),
1019
1047
  mode: "plan", // explore is always read-only
1020
1048
  dryRun: false,
1021
1049
  assumeYes: false,
@@ -1085,7 +1113,10 @@ export async function runExplore(options) {
1085
1113
  * Requirements: 14.7
1086
1114
  */
1087
1115
  function formatTimestamp(timestamp) {
1088
- const date = new Date(timestamp.endsWith("Z") ? timestamp : timestamp + "Z");
1116
+ // SQLite CURRENT_TIMESTAMP returns "YYYY-MM-DD HH:MM:SS" (space, no T, no Z).
1117
+ // Normalize to ISO 8601 so Date() parses it as UTC.
1118
+ const normalized = timestamp.includes('T') ? timestamp : timestamp.replace(' ', 'T');
1119
+ const date = new Date(normalized.endsWith("Z") ? normalized : normalized + "Z");
1089
1120
  const now = Date.now();
1090
1121
  const diffMs = now - date.getTime();
1091
1122
  const diffSec = Math.floor(diffMs / 1000);
@@ -1362,7 +1393,15 @@ function setNestedValue(obj, key, value) {
1362
1393
  let current = result;
1363
1394
  for (let i = 0; i < parts.length - 1; i++) {
1364
1395
  const part = parts[i];
1365
- current[part] = { ...(current[part] ?? {}) };
1396
+ const existing = current[part];
1397
+ // If the intermediate value is not an object, replace it with an empty object.
1398
+ // This prevents spreading a primitive (string/number/boolean) into an object.
1399
+ if (existing === null || typeof existing !== 'object' || Array.isArray(existing)) {
1400
+ current[part] = {};
1401
+ }
1402
+ else {
1403
+ current[part] = { ...existing };
1404
+ }
1366
1405
  current = current[part];
1367
1406
  }
1368
1407
  current[parts[parts.length - 1]] = value;
@@ -1683,31 +1722,41 @@ export async function runDoctor(options = {}) {
1683
1722
  }
1684
1723
  }
1685
1724
  // -------------------------------------------------------------------------
1686
- // 6. Provider readiness — API key presence (Req 16.7) — CRITICAL
1725
+ // 6. Provider readiness — API key presence (Req 16.7) — CRITICAL for default
1726
+ // v0.2.2: report all configured providers, fail only if default key is missing
1687
1727
  // -------------------------------------------------------------------------
1688
1728
  {
1689
- const provider = config?.provider.default ?? "anthropic";
1729
+ const defaultProvider = config?.provider.default ?? "anthropic";
1690
1730
  const keyMap = {
1691
1731
  anthropic: "ANTHROPIC_API_KEY",
1692
1732
  openai: "OPENAI_API_KEY",
1693
1733
  openrouter: "OPENROUTER_API_KEY",
1694
- ollama: "", // no key needed
1734
+ ollama: null, // no key needed
1695
1735
  };
1696
- const envKey = keyMap[provider];
1697
- if (!envKey) {
1698
- // Ollama no API key required
1699
- checks.push({ name: "provider", status: "pass", message: `${provider} (no API key required)` });
1736
+ // Critical check: default provider must be ready
1737
+ const defaultEnvKey = keyMap[defaultProvider];
1738
+ if (defaultEnvKey === null) {
1739
+ checks.push({ name: "provider", status: "pass", message: `${defaultProvider} (no API key required)` });
1700
1740
  }
1701
- else if (process.env[envKey]) {
1702
- checks.push({ name: "provider", status: "pass", message: `${provider} (${envKey} present)` });
1741
+ else if (process.env[defaultEnvKey]) {
1742
+ const model = config?.provider.model ?? "default";
1743
+ checks.push({ name: "provider", status: "pass", message: `${defaultProvider} (${defaultEnvKey} present, model: ${model})` });
1703
1744
  }
1704
1745
  else {
1705
1746
  checks.push({
1706
1747
  name: "provider",
1707
1748
  status: "fail",
1708
- message: `${provider} (${envKey} not set)`,
1749
+ message: `${defaultProvider} (${defaultEnvKey} not set)`,
1709
1750
  });
1710
1751
  }
1752
+ // Non-critical: only report secondary providers that are actually configured (key present)
1753
+ const secondaryProviders = Object.entries(keyMap).filter(([name]) => name !== defaultProvider && name !== "ollama");
1754
+ for (const [name, envKey] of secondaryProviders) {
1755
+ if (envKey && process.env[envKey]) {
1756
+ checks.push({ name: `provider:${name}`, status: "pass", message: `${name} (${envKey} present)` });
1757
+ }
1758
+ // Don't warn about unconfigured secondary providers — too noisy on vanilla installs
1759
+ }
1711
1760
  }
1712
1761
  // -------------------------------------------------------------------------
1713
1762
  // 7. Project type detection (Req 16.8)
@@ -1729,20 +1778,40 @@ export async function runDoctor(options = {}) {
1729
1778
  }
1730
1779
  }
1731
1780
  // -------------------------------------------------------------------------
1732
- // 8. Prisma schema existence if Prisma detected (Req 16.9)
1781
+ // 8. Prisma schema existence and model count (Req 16.9 + v0.2.0)
1733
1782
  // -------------------------------------------------------------------------
1734
1783
  {
1735
1784
  try {
1736
1785
  const project = detectProjectType(projectRoot);
1737
1786
  if (project.hasPrisma) {
1738
1787
  if (project.prismaSchemaPath && existsSync(project.prismaSchemaPath)) {
1739
- checks.push({ name: "prisma", status: "pass", message: `detected at ${project.prismaSchemaPath}` });
1788
+ // v0.2.0: parse schema and report model count + provider
1789
+ try {
1790
+ const { parsePrismaSchema } = await import('./db/schema.js');
1791
+ const schemaInfo = parsePrismaSchema(projectRoot);
1792
+ if (schemaInfo) {
1793
+ const providerLabel = schemaInfo.datasourceProvider ?? 'unknown';
1794
+ checks.push({
1795
+ name: 'prisma',
1796
+ status: 'pass',
1797
+ message: `${schemaInfo.path} (${providerLabel}, ${schemaInfo.models.length} models)`,
1798
+ });
1799
+ }
1800
+ else {
1801
+ checks.push({ name: 'prisma', status: 'pass', message: `detected at ${project.prismaSchemaPath}` });
1802
+ }
1803
+ }
1804
+ catch {
1805
+ checks.push({ name: 'prisma', status: 'pass', message: `detected at ${project.prismaSchemaPath}` });
1806
+ }
1740
1807
  }
1741
1808
  else {
1742
- checks.push({ name: "prisma", status: "warn", message: "dependency detected but prisma/schema.prisma not found" });
1809
+ checks.push({ name: 'prisma', status: 'warn', message: 'dependency detected but prisma/schema.prisma not found' });
1743
1810
  }
1744
1811
  }
1745
- // If no Prisma, skip this check entirely
1812
+ else {
1813
+ checks.push({ name: 'prisma', status: 'warn', message: 'no schema.prisma found (db commands unavailable)' });
1814
+ }
1746
1815
  }
1747
1816
  catch {
1748
1817
  // project detection already reported above