programmatic subagents
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

feat(cli-help): show model catalog for selected driver (config default or --driver)

+71 -10
+2 -2
README.md
··· 50 50 51 51 All commands accept `--json` for machine-readable output on stdout (diagnostics go to stderr). 52 52 53 - `mill --help` and `mill <command> --help` include a **Models** section. Those model lists are sourced from each configured driver's `codec.modelCatalog` effect (via resolved `mill.config.ts`), so driver registrations are what inform the CLI/main agent about available models. 53 + `mill --help` and `mill <command> --help` include a **Models** section for the selected driver (`defaultDriver` from resolved config, or `--driver` override on command help). The list is sourced from that driver's `codec.modelCatalog`, so driver registration is what informs the CLI/main agent about available models. 54 54 55 55 ## FAQ 56 56 ··· 93 93 - `@mill/driver-claude`: built-in default catalog (`sonnet`, `opus`, `haiku`) unless overridden in config. 94 94 - `@mill/driver-codex`: built-in default catalog (`openai-codex/gpt-5.3-codex`) unless overridden in config. 95 95 96 - These driver catalogs flow into CLI help (`mill --help`, `mill <command> --help`) through each driver's `codec.modelCatalog`. In short: driver registration is how model availability is communicated to the CLI/main agent. 96 + These driver catalogs flow into CLI help (`mill --help`, `mill <command> --help`) through the selected driver's `codec.modelCatalog`. In short: driver registration is how model availability is communicated to the CLI/main agent. 97 97 98 98 ## Internals 99 99
+33 -4
packages/cli/src/public/index.api.test.ts
··· 848 848 expect(code).toBe(0); 849 849 expect(stderr).toHaveLength(0); 850 850 expect(stdout[0]).toContain("Models:"); 851 - expect(stdout[0]).toContain("codex (provider/model-id): openai-codex/gpt-5.3-codex"); 851 + expect(stdout[0]).toContain("pi (provider/model-id):"); 852 + expect(stdout[0]).not.toContain("codex (provider/model-id):"); 852 853 expect(stdout[0]).toContain("Authoring:\n CUSTOM_AUTHORING_INSTRUCTIONS"); 853 854 expect(stdout[0]).not.toContain("systemPrompt = WHO the agent is"); 854 855 }); ··· 879 880 expect(code).toBe(0); 880 881 expect(stderr).toHaveLength(0); 881 882 expect(stdout[0]).toContain("Models:"); 882 - expect(stdout[0]).toContain("claude (provider/model-id): anthropic/claude-sonnet-4-6"); 883 + expect(stdout[0]).toContain("pi (provider/model-id):"); 884 + expect(stdout[0]).not.toContain("claude (provider/model-id):"); 883 885 expect(stdout[0]).toContain("systemPrompt = WHO the agent is"); 884 886 expect(stdout[0]).toContain("prompt = WHAT to do now"); 885 887 expect(stdout[0]).not.toContain("From config:"); ··· 916 918 "Authoring (from config): CUSTOM_AUTHORING_IN_COMMAND_HELP", 917 919 ); 918 920 expect(stdout.join("\n")).toContain("Models:"); 921 + expect(stdout.join("\n")).toContain("pi (provider/model-id):"); 922 + expect(stdout.join("\n")).not.toContain("codex (provider/model-id):"); 923 + expect(stdout.join("\n")).not.toContain("systemPrompt = WHO the agent is"); 924 + }); 925 + 926 + it("honors --driver override in command help model catalog", async () => { 927 + const stdout: Array<string> = []; 928 + const stderr: Array<string> = []; 929 + 930 + const code = await runCli(["run", "--help", "--driver", "codex"], { 931 + cwd: "/workspace/repo", 932 + homeDirectory: "/Users/tester", 933 + pathExists: async () => false, 934 + io: { 935 + stdout: (line) => { 936 + stdout.push(line); 937 + }, 938 + stderr: (line) => { 939 + stderr.push(line); 940 + }, 941 + }, 942 + }); 943 + 944 + expect(code).toBe(0); 945 + expect(stderr).toHaveLength(0); 946 + expect(stdout.join("\n")).toContain("Models:"); 919 947 expect(stdout.join("\n")).toContain("codex (provider/model-id): openai-codex/gpt-5.3-codex"); 920 - expect(stdout.join("\n")).not.toContain("systemPrompt = WHO the agent is"); 948 + expect(stdout.join("\n")).not.toContain("pi (provider/model-id):"); 921 949 }); 922 950 923 951 it("falls back to static authoring guidance in command help when config omits authoring", async () => { ··· 947 975 expect(stderr).toHaveLength(0); 948 976 expect(stdout.join("\n")).toContain("Authoring:\n systemPrompt = WHO the agent is"); 949 977 expect(stdout.join("\n")).toContain("Models:"); 950 - expect(stdout.join("\n")).toContain("claude (provider/model-id): anthropic/claude-sonnet-4-6"); 978 + expect(stdout.join("\n")).toContain("pi (provider/model-id):"); 979 + expect(stdout.join("\n")).not.toContain("claude (provider/model-id):"); 951 980 expect(stdout.join("\n")).not.toContain("Authoring (from config):"); 952 981 }); 953 982
+36 -4
packages/cli/src/public/index.api.ts
··· 826 826 return argv.slice(1).some((argument) => HELP_FLAGS.has(argument)); 827 827 }; 828 828 829 - const resolveHelpContextForHelp = async (options: RunCliOptions): Promise<ResolvedHelpContext> => { 829 + const extractDriverOverride = (argv: ReadonlyArray<string>): string | undefined => { 830 + for (let index = 0; index < argv.length; index += 1) { 831 + const argument = argv[index]; 832 + 833 + if (argument === "--driver") { 834 + const next = argv[index + 1]; 835 + if (next !== undefined && next.length > 0 && !next.startsWith("--")) { 836 + return next; 837 + } 838 + continue; 839 + } 840 + 841 + if (argument?.startsWith("--driver=") === true) { 842 + const value = argument.slice("--driver=".length); 843 + if (value.length > 0) { 844 + return value; 845 + } 846 + } 847 + } 848 + 849 + return undefined; 850 + }; 851 + 852 + const resolveHelpContextForHelp = async ( 853 + options: RunCliOptions, 854 + selectedDriverName?: string, 855 + ): Promise<ResolvedHelpContext> => { 830 856 try { 831 857 const resolvedConfig = await resolveConfig({ 832 858 defaults: defaultConfig, ··· 854 880 left.driverName.localeCompare(right.driverName), 855 881 ); 856 882 883 + const preferredDriver = selectedDriverName ?? resolvedConfig.config.defaultDriver; 884 + const selectedDriverEntry = driverEntries.find((entry) => entry.driverName === preferredDriver); 885 + 857 886 return { 858 887 authoring: hasAuthoringOverride 859 888 ? { ··· 865 894 }, 866 895 modelCatalog: { 867 896 source: "resolved", 868 - entries: driverEntries, 897 + entries: selectedDriverEntry === undefined ? driverEntries : [selectedDriverEntry], 869 898 }, 870 899 }; 871 900 } catch { ··· 890 919 const io = resolvedOptions.io ?? defaultIo; 891 920 892 921 if (isHelpRequest(argv)) { 893 - const helpContext = await resolveHelpContextForHelp(resolvedOptions); 922 + const helpContext = await resolveHelpContextForHelp( 923 + resolvedOptions, 924 + extractDriverOverride(argv), 925 + ); 894 926 io.stdout(buildHelpText(helpContext)); 895 927 return 0; 896 928 } 897 929 898 930 const commandHelpRequest = isCommandHelpRequest(argv); 899 931 const helpContext = commandHelpRequest 900 - ? await resolveHelpContextForHelp(resolvedOptions) 932 + ? await resolveHelpContextForHelp(resolvedOptions, extractDriverOverride(argv)) 901 933 : undefined; 902 934 903 935 const command = createCli(resolvedOptions, io);