@justram/pie 0.1.1 → 0.2.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.
package/CHANGELOG.md CHANGED
@@ -12,6 +12,44 @@
12
12
 
13
13
  ### Removed
14
14
 
15
+ ## 0.2.1
16
+
17
+ ### Breaking Changes
18
+
19
+ ### Added
20
+
21
+ ### Changed
22
+
23
+ ### Fixed
24
+
25
+ - Restored minimal `AGENTS.md` pointing to `docs/` onboarding.
26
+
27
+ ### Removed
28
+
29
+ ## 0.2.0
30
+
31
+ ### Breaking Changes
32
+
33
+ ### Added
34
+
35
+ - Added `--list-models` plus filtering/paging/JSON flags to inspect available provider models.
36
+ - Added detailed progress output for `scripts/preindex.ts`, with concise tool/file status and periodic counters.
37
+ - Defaulted `scripts/preindex.ts` to incremental updates based on git changes to reduce token usage.
38
+ - Added clear logging for why a full update is selected in `scripts/preindex.ts`.
39
+ - Added token usage summary logging after preindex runs.
40
+ - Added untracked file detection to `scripts/preindex.ts` so incremental updates include new files.
41
+
42
+ ### Changed
43
+
44
+ - Added `examples/hn-insights` and moved the HN insights script into the examples folder.
45
+ - Expanded onboarding docs with example/script prerequisites and model listing flags.
46
+
47
+ ### Fixed
48
+
49
+ - Removed TypeScript syntax from `bin/pie` to keep the CLI runnable under Node.
50
+
51
+ ### Removed
52
+
15
53
  ## 0.1.1
16
54
 
17
55
  ### Breaking Changes
package/README.md CHANGED
@@ -28,6 +28,13 @@ cat input.txt | pie \
28
28
  --model anthropic/claude-sonnet-4-5
29
29
  ```
30
30
 
31
+ List available models (with optional filters):
32
+
33
+ ```bash
34
+ pie --list-models --models-provider google-antigravity
35
+ pie --list-models --models-provider google-antigravity --models-filter gemini
36
+ ```
37
+
31
38
  ### Authentication (API keys and OAuth)
32
39
 
33
40
  `pie` does not require Pi to be installed. It uses the OAuth helpers from `@mariozechner/pi-ai` and stores credentials in `~/.pi/agent/auth.json` (created automatically on first login).
package/bin/pie CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  import { runCli } from "../dist/cli.js";
4
4
 
5
- async function main(): Promise<void> {
5
+ async function main() {
6
6
  const exitCode = await runCli(process.argv.slice(2));
7
7
  process.exitCode = exitCode;
8
8
  }
@@ -18,6 +18,12 @@ export interface CliArgs {
18
18
  recipeConfig?: string;
19
19
  recipeVars?: string;
20
20
  listRecipes?: boolean;
21
+ listModels?: boolean;
22
+ listModelsProvider?: string;
23
+ listModelsFilter?: string;
24
+ listModelsJson?: boolean;
25
+ listModelsLimit?: number;
26
+ listModelsOffset?: number;
21
27
  login?: string;
22
28
  help?: boolean;
23
29
  version?: boolean;
package/dist/cli/args.js CHANGED
@@ -127,6 +127,58 @@ export function parseArgs(argv) {
127
127
  case "--list-recipes":
128
128
  args.listRecipes = true;
129
129
  break;
130
+ case "--list-models":
131
+ args.listModels = true;
132
+ break;
133
+ case "--models-provider":
134
+ case "--provider": {
135
+ const value = nextValue(arg);
136
+ if (value) {
137
+ args.listModelsProvider = value;
138
+ args.listModels = true;
139
+ }
140
+ break;
141
+ }
142
+ case "--models-filter": {
143
+ const value = nextValue(arg);
144
+ if (value) {
145
+ args.listModelsFilter = value;
146
+ args.listModels = true;
147
+ }
148
+ break;
149
+ }
150
+ case "--models-json":
151
+ args.listModelsJson = true;
152
+ args.listModels = true;
153
+ break;
154
+ case "--models-limit": {
155
+ const value = nextValue(arg);
156
+ if (!value)
157
+ break;
158
+ const parsed = Number.parseInt(value, 10);
159
+ if (!Number.isFinite(parsed) || parsed < 0) {
160
+ errors.push(`Invalid value for ${arg}: ${value}`);
161
+ }
162
+ else {
163
+ args.listModelsLimit = parsed;
164
+ args.listModels = true;
165
+ }
166
+ break;
167
+ }
168
+ case "--models-offset": {
169
+ const value = nextValue(arg);
170
+ if (!value)
171
+ break;
172
+ const parsed = Number.parseInt(value, 10);
173
+ if (!Number.isFinite(parsed) || parsed < 0) {
174
+ errors.push(`Invalid value for ${arg}: ${value}`);
175
+ }
176
+ else {
177
+ args.listModelsOffset = parsed;
178
+ args.listModels = true;
179
+ }
180
+ break;
181
+ }
130
182
  case "--login": {
131
183
  const value = nextValue(arg);
132
184
  if (value)
@@ -178,6 +230,12 @@ Options:
178
230
  --recipe-config <file> Use a recipe config file (default: setup.md)
179
231
  --recipe-vars <json> JSON object for recipe template vars
180
232
  --list-recipes List available recipes and exit
233
+ --list-models List available models and exit
234
+ --models-provider <name> Filter models by provider (alias: --provider)
235
+ --models-filter <text> Filter models by id or name substring
236
+ --models-limit <n> Limit models output (for paging)
237
+ --models-offset <n> Skip first N models (for paging)
238
+ --models-json Output models as JSON
181
239
  --login <provider> OAuth login for a provider (e.g. anthropic)
182
240
  -h, --help Show help
183
241
  -v, --version Show version
package/dist/main.js CHANGED
@@ -82,6 +82,45 @@ async function runCliInternal(argv, deps, stdout, stderr) {
82
82
  }
83
83
  return 0;
84
84
  }
85
+ if (args.listModels) {
86
+ const providerFilter = args.listModelsProvider;
87
+ if (providerFilter && !isKnownProvider(providerFilter)) {
88
+ throw new CliExitError(`Unknown provider: ${providerFilter}`, 2);
89
+ }
90
+ const providers = providerFilter ? [providerFilter] : getProviders();
91
+ const filter = args.listModelsFilter?.toLowerCase();
92
+ const entries = providers
93
+ .slice()
94
+ .sort((left, right) => left.localeCompare(right))
95
+ .flatMap((provider) => getModels(provider)
96
+ .slice()
97
+ .sort((left, right) => left.id.localeCompare(right.id))
98
+ .filter((model) => {
99
+ if (!filter) {
100
+ return true;
101
+ }
102
+ const id = model.id.toLowerCase();
103
+ const name = model.name?.toLowerCase() ?? "";
104
+ return id.includes(filter) || name.includes(filter);
105
+ })
106
+ .map((model) => ({
107
+ provider,
108
+ id: model.id,
109
+ name: model.name ?? null,
110
+ })));
111
+ const offset = args.listModelsOffset ?? 0;
112
+ const limit = args.listModelsLimit;
113
+ const sliced = limit === undefined ? entries.slice(offset) : entries.slice(offset, offset + limit);
114
+ if (args.listModelsJson) {
115
+ stdout.write(`${JSON.stringify(sliced, null, 2)}\n`);
116
+ return 0;
117
+ }
118
+ for (const entry of sliced) {
119
+ const name = entry.name ? `\t${entry.name}` : "";
120
+ stdout.write(`${entry.provider}\t${entry.id}${name}\n`);
121
+ }
122
+ return 0;
123
+ }
85
124
  const promptInput = args.promptFile ? readTextFile(args.promptFile, "prompt") : args.prompt;
86
125
  const promptPath = args.promptFile ? resolve(args.promptFile) : undefined;
87
126
  const promptIsSetup = !args.config && !useRecipe && typeof promptInput === "string" && promptInput.startsWith("---");
package/dist/models.d.ts CHANGED
@@ -3,7 +3,7 @@
3
3
  *
4
4
  * Usage:
5
5
  * ```typescript
6
- * import { getModel, getModels, getProviders } from "pie";
6
+ * import { getModel, getModels, getProviders } from "@justram/pie";
7
7
  *
8
8
  * // Get specific model
9
9
  * const model = getModel("anthropic", "claude-sonnet-4-5");
package/dist/models.js CHANGED
@@ -3,7 +3,7 @@
3
3
  *
4
4
  * Usage:
5
5
  * ```typescript
6
- * import { getModel, getModels, getProviders } from "pie";
6
+ * import { getModel, getModels, getProviders } from "@justram/pie";
7
7
  *
8
8
  * // Get specific model
9
9
  * const model = getModel("anthropic", "claude-sonnet-4-5");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@justram/pie",
3
- "version": "0.1.1",
3
+ "version": "0.2.1",
4
4
  "description": "Structured extraction library and CLI built on @mariozechner/pi-ai.",
5
5
  "license": "MIT",
6
6
  "keywords": [