jouzu 0.1.0 → 0.1.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 (94) hide show
  1. package/README.md +8 -6
  2. package/dist/args.d.ts +1 -0
  3. package/dist/args.d.ts.map +1 -1
  4. package/dist/args.js +8 -4
  5. package/dist/args.js.map +1 -1
  6. package/dist/cli.js +15 -3
  7. package/dist/cli.js.map +1 -1
  8. package/dist/doctor.d.ts +29 -0
  9. package/dist/doctor.d.ts.map +1 -1
  10. package/dist/doctor.js +140 -87
  11. package/dist/doctor.js.map +1 -1
  12. package/dist/help.d.ts +3 -0
  13. package/dist/help.d.ts.map +1 -0
  14. package/dist/help.js +42 -0
  15. package/dist/help.js.map +1 -0
  16. package/dist/keybindings.d.ts +1 -1
  17. package/dist/keybindings.d.ts.map +1 -1
  18. package/dist/keybindings.js +109 -28
  19. package/dist/keybindings.js.map +1 -1
  20. package/dist/metadata.d.ts +11 -0
  21. package/dist/metadata.d.ts.map +1 -1
  22. package/dist/metadata.js +54 -0
  23. package/dist/metadata.js.map +1 -1
  24. package/dist/model-picker-ranking.d.ts +37 -0
  25. package/dist/model-picker-ranking.d.ts.map +1 -0
  26. package/dist/model-picker-ranking.js +169 -0
  27. package/dist/model-picker-ranking.js.map +1 -0
  28. package/dist/model-picker-state.d.ts +64 -0
  29. package/dist/model-picker-state.d.ts.map +1 -0
  30. package/dist/model-picker-state.js +319 -0
  31. package/dist/model-picker-state.js.map +1 -0
  32. package/dist/model-picker.d.ts +65 -0
  33. package/dist/model-picker.d.ts.map +1 -0
  34. package/dist/model-picker.js +446 -0
  35. package/dist/model-picker.js.map +1 -0
  36. package/dist/palette.d.ts +36 -0
  37. package/dist/palette.d.ts.map +1 -0
  38. package/dist/palette.js +69 -0
  39. package/dist/palette.js.map +1 -0
  40. package/dist/pi.lock.json +7 -6
  41. package/dist/presentation.d.ts +4 -1
  42. package/dist/presentation.d.ts.map +1 -1
  43. package/dist/presentation.js +30 -31
  44. package/dist/presentation.js.map +1 -1
  45. package/dist/private-fs.d.ts +14 -0
  46. package/dist/private-fs.d.ts.map +1 -1
  47. package/dist/private-fs.js +35 -2
  48. package/dist/private-fs.js.map +1 -1
  49. package/dist/profile-choice.d.ts.map +1 -1
  50. package/dist/profile-choice.js +4 -20
  51. package/dist/profile-choice.js.map +1 -1
  52. package/dist/profile-manager.d.ts.map +1 -1
  53. package/dist/profile-manager.js +4 -22
  54. package/dist/profile-manager.js.map +1 -1
  55. package/dist/session-ui/THIRD_PARTY_NOTICES.md +30 -0
  56. package/dist/session-ui/color.js +76 -0
  57. package/dist/session-ui/color.js.map +1 -0
  58. package/dist/session-ui/contracts.js +4 -0
  59. package/dist/session-ui/contracts.js.map +1 -0
  60. package/dist/session-ui/controller.js +116 -0
  61. package/dist/session-ui/controller.js.map +1 -0
  62. package/dist/session-ui/extension.js +77 -0
  63. package/dist/session-ui/extension.js.map +1 -0
  64. package/dist/session-ui/identity.js +9 -0
  65. package/dist/session-ui/identity.js.map +1 -0
  66. package/dist/session-ui/index.js +15 -0
  67. package/dist/session-ui/index.js.map +1 -0
  68. package/dist/session-ui/layout.js +138 -0
  69. package/dist/session-ui/layout.js.map +1 -0
  70. package/dist/session-ui/prompt-frame.js +107 -0
  71. package/dist/session-ui/prompt-frame.js.map +1 -0
  72. package/dist/session-ui/session-line.js +82 -0
  73. package/dist/session-ui/session-line.js.map +1 -0
  74. package/dist/session-ui/snapshot.js +68 -0
  75. package/dist/session-ui/snapshot.js.map +1 -0
  76. package/dist/session-ui/sources/command.js +2 -0
  77. package/dist/session-ui/sources/command.js.map +1 -0
  78. package/dist/session-ui/sources/git.js +79 -0
  79. package/dist/session-ui/sources/git.js.map +1 -0
  80. package/dist/session-ui/sources/runtime.js +95 -0
  81. package/dist/session-ui/sources/runtime.js.map +1 -0
  82. package/dist/session-ui/status-bar.js +265 -0
  83. package/dist/session-ui/status-bar.js.map +1 -0
  84. package/dist/session-ui/styles.js +91 -0
  85. package/dist/session-ui/styles.js.map +1 -0
  86. package/dist/terminal-layout.d.ts +2 -0
  87. package/dist/terminal-layout.d.ts.map +1 -0
  88. package/dist/terminal-layout.js +2 -0
  89. package/dist/terminal-layout.js.map +1 -0
  90. package/dist/updater.d.ts +1 -0
  91. package/dist/updater.d.ts.map +1 -1
  92. package/dist/updater.js +18 -23
  93. package/dist/updater.js.map +1 -1
  94. package/package.json +5 -3
@@ -0,0 +1,169 @@
1
+ import { modelReferenceKey, modelReferencesEqual } from "./model-picker-state.js";
2
+ import { sanitizeTerminalText } from "./terminal-layout.js";
3
+ function normalized(value) {
4
+ return value.normalize("NFKC").toLowerCase();
5
+ }
6
+ function searchScore(model, query) {
7
+ const needle = normalized(query.trim());
8
+ if (!needle)
9
+ return 0;
10
+ const provider = normalized(model.display?.provider ?? sanitizeTerminalText(model.provider));
11
+ const modelId = normalized(model.display?.modelId ?? sanitizeTerminalText(model.modelId));
12
+ const exact = `${provider}/${modelId}`;
13
+ const name = normalized(model.display?.name ?? sanitizeTerminalText(model.name));
14
+ if (exact === needle)
15
+ return 0;
16
+ if (modelId === needle)
17
+ return 1;
18
+ if (name === needle)
19
+ return 2;
20
+ if (exact.startsWith(needle))
21
+ return 10 + exact.length - needle.length;
22
+ if (modelId.startsWith(needle))
23
+ return 20 + modelId.length - needle.length;
24
+ if (name.startsWith(needle))
25
+ return 30 + name.length - needle.length;
26
+ const fields = [exact, `${provider} ${modelId}`, name];
27
+ let best;
28
+ for (const field of fields) {
29
+ const substring = field.indexOf(needle);
30
+ if (substring >= 0) {
31
+ const score = 100 + substring * 2 + field.length - needle.length;
32
+ best = best === undefined ? score : Math.min(best, score);
33
+ continue;
34
+ }
35
+ let cursor = 0;
36
+ let gaps = 0;
37
+ for (const character of needle) {
38
+ const index = field.indexOf(character, cursor);
39
+ if (index < 0) {
40
+ cursor = -1;
41
+ break;
42
+ }
43
+ gaps += index - cursor;
44
+ cursor = index + 1;
45
+ }
46
+ if (cursor >= 0) {
47
+ const score = 500 + gaps * 3 + field.length - needle.length;
48
+ best = best === undefined ? score : Math.min(best, score);
49
+ }
50
+ }
51
+ return best;
52
+ }
53
+ function contextFit(model, activeContextTokens) {
54
+ if (activeContextTokens === undefined || activeContextTokens === null || !model.contextWindow)
55
+ return "unknown";
56
+ const outputReserve = Math.max(0, Math.min(model.maxTokens ?? 0, model.contextWindow));
57
+ return activeContextTokens <= model.contextWindow - outputReserve ? "fits" : "too-small";
58
+ }
59
+ function resolvedModels(options) {
60
+ const models = new Map();
61
+ for (const model of options.models) {
62
+ models.set(modelReferenceKey(model), {
63
+ ...model,
64
+ display: {
65
+ provider: sanitizeTerminalText(model.provider),
66
+ modelId: sanitizeTerminalText(model.modelId),
67
+ name: sanitizeTerminalText(model.name),
68
+ },
69
+ });
70
+ }
71
+ for (const favorite of options.state.favorites) {
72
+ const key = modelReferenceKey(favorite);
73
+ if (!models.has(key)) {
74
+ models.set(key, {
75
+ provider: favorite.provider,
76
+ modelId: favorite.modelId,
77
+ name: favorite.modelId,
78
+ available: false,
79
+ display: {
80
+ provider: sanitizeTerminalText(favorite.provider),
81
+ modelId: sanitizeTerminalText(favorite.modelId),
82
+ name: sanitizeTerminalText(favorite.modelId),
83
+ },
84
+ });
85
+ }
86
+ }
87
+ return models;
88
+ }
89
+ function favoriteScopes(options, reference) {
90
+ const scopes = new Set();
91
+ for (const favorite of options.state.favorites) {
92
+ if (!modelReferencesEqual(favorite, reference))
93
+ continue;
94
+ if (favorite.scope === "global")
95
+ scopes.add("global");
96
+ if (favorite.scope === "project" && favorite.projectKey === options.projectKey)
97
+ scopes.add("project");
98
+ }
99
+ return [...scopes].sort((left) => (left === "project" ? -1 : 1));
100
+ }
101
+ export function buildPickerRows(options) {
102
+ const models = resolvedModels(options);
103
+ const filter = options.filter ?? "recent";
104
+ const query = options.query?.trim() ?? "";
105
+ const rows = [];
106
+ const seen = new Set();
107
+ const projectDefault = options.state.defaults.projects[options.projectKey];
108
+ const add = (reference, section, recentScope) => {
109
+ if (!reference)
110
+ return;
111
+ const key = modelReferenceKey(reference);
112
+ if (seen.has(key))
113
+ return;
114
+ const model = models.get(key);
115
+ if (!model)
116
+ return;
117
+ seen.add(key);
118
+ rows.push({
119
+ section,
120
+ model,
121
+ contextFit: contextFit(model, options.activeContextTokens),
122
+ favoriteScopes: favoriteScopes(options, model),
123
+ ...(recentScope ? { recentScope } : {}),
124
+ projectDefault: modelReferencesEqual(projectDefault, model),
125
+ rank: rows.length,
126
+ });
127
+ };
128
+ if (filter === "recent") {
129
+ add(options.current, "current");
130
+ for (const reference of options.previous ?? [])
131
+ add(reference, "previous");
132
+ for (const recent of options.state.recents.projects[options.projectKey] ?? []) {
133
+ add(recent, "project_recent", "project");
134
+ }
135
+ for (const recent of options.state.recents.global)
136
+ add(recent, "global_recent", "global");
137
+ }
138
+ else if (filter === "favorite") {
139
+ for (const favorite of options.state.favorites) {
140
+ if (favorite.scope === "project" && favorite.projectKey === options.projectKey)
141
+ add(favorite, "favorite");
142
+ }
143
+ for (const favorite of options.state.favorites) {
144
+ if (favorite.scope === "global")
145
+ add(favorite, "favorite");
146
+ }
147
+ }
148
+ else {
149
+ for (const model of options.models)
150
+ add(model, "all");
151
+ }
152
+ if (!query)
153
+ return rows.slice(0, options.maxRows ?? Number.MAX_SAFE_INTEGER);
154
+ const compareIdentity = (left, right) => {
155
+ const leftKey = modelReferenceKey(left.model);
156
+ const rightKey = modelReferenceKey(right.model);
157
+ return leftKey < rightKey ? -1 : leftKey > rightKey ? 1 : 0;
158
+ };
159
+ return rows
160
+ .map((row) => ({ row, score: searchScore(row.model, query) }))
161
+ .filter((value) => value.score !== undefined)
162
+ .sort((left, right) => left.score - right.score ||
163
+ Number(right.row.model.available) - Number(left.row.model.available) ||
164
+ (filter === "all" ? 0 : left.row.rank - right.row.rank) ||
165
+ compareIdentity(left.row, right.row))
166
+ .slice(0, options.maxRows ?? 200)
167
+ .map(({ row, score }) => ({ ...row, rank: score }));
168
+ }
169
+ //# sourceMappingURL=model-picker-ranking.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"model-picker-ranking.js","sourceRoot":"","sources":["../src/model-picker-ranking.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,64 @@
1
+ import type { JouzuPaths } from "./paths.js";
2
+ export declare const MODEL_PICKER_SCHEMA_VERSION = 2;
3
+ export declare const MODEL_PICKER_RECENT_LIMIT = 12;
4
+ export declare const MODEL_PICKER_HISTORY_LIMIT = 8;
5
+ export interface ModelReference {
6
+ provider: string;
7
+ modelId: string;
8
+ }
9
+ export type FavoriteScope = "global" | "project";
10
+ export interface FavoriteRecord extends ModelReference {
11
+ scope: FavoriteScope;
12
+ projectKey?: string;
13
+ addedAt: string;
14
+ }
15
+ export interface RecentRecord extends ModelReference {
16
+ lastUsedAt: string;
17
+ useCount: number;
18
+ }
19
+ export interface ModelPickerState {
20
+ schemaVersion: 2;
21
+ favorites: FavoriteRecord[];
22
+ defaults: {
23
+ projects: Record<string, ModelReference>;
24
+ };
25
+ recents: {
26
+ global: RecentRecord[];
27
+ projects: Record<string, RecentRecord[]>;
28
+ };
29
+ }
30
+ export interface ModelPickerStateLoadResult {
31
+ state: ModelPickerState;
32
+ warning?: string;
33
+ quarantinePath?: string;
34
+ }
35
+ export declare class ModelPickerStateError extends Error {
36
+ constructor(message: string);
37
+ }
38
+ export declare function modelReferenceKey(reference: ModelReference): string;
39
+ export declare function modelReferencesEqual(left: ModelReference | undefined, right: ModelReference | undefined): boolean;
40
+ export declare function emptyModelPickerState(): ModelPickerState;
41
+ export declare function loadModelPickerState(paths: JouzuPaths, options?: {
42
+ recover?: boolean;
43
+ now?: Date;
44
+ }): ModelPickerStateLoadResult;
45
+ export declare class ModelPickerStore {
46
+ private readonly paths;
47
+ constructor(paths: JouzuPaths);
48
+ load(options?: {
49
+ recover?: boolean;
50
+ now?: Date;
51
+ }): ModelPickerStateLoadResult;
52
+ private mutate;
53
+ setProjectDefault(reference: ModelReference, projectKey: string, now?: Date): ModelPickerState;
54
+ recordDispatch(reference: ModelReference, projectKey: string, now?: Date): ModelPickerState;
55
+ toggleFavorite(reference: ModelReference, scope: FavoriteScope, projectKey?: string, now?: Date): ModelPickerState;
56
+ clearRecents(scope: "global" | "project" | "all", projectKey?: string, now?: Date): ModelPickerState;
57
+ }
58
+ export declare function deriveProjectKey(cwd: string, options?: {
59
+ runGit?: (cwd: string) => string | undefined;
60
+ realpath?: (path: string) => string;
61
+ }): string;
62
+ export declare function projectDefaultAppliesAtStartup(args: readonly string[]): boolean;
63
+ export declare function previousModelStack(entries: readonly unknown[], current: ModelReference | undefined, limit?: number): ModelReference[];
64
+ //# sourceMappingURL=model-picker-state.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"model-picker-state.d.ts","sourceRoot":"","sources":["../src/model-picker-state.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,319 @@
1
+ import { spawnSync } from "node:child_process";
2
+ import { createHash } from "node:crypto";
3
+ import { existsSync, lstatSync, readFileSync, realpathSync, renameSync } from "node:fs";
4
+ import { isAbsolute, join, resolve } from "node:path";
5
+ import { ensurePrivateDirectory, writeFilePrivateAtomic } from "./private-fs.js";
6
+ import { acquireStateLock } from "./state-lock.js";
7
+ export const MODEL_PICKER_SCHEMA_VERSION = 2;
8
+ export const MODEL_PICKER_RECENT_LIMIT = 12;
9
+ export const MODEL_PICKER_HISTORY_LIMIT = 8;
10
+ export class ModelPickerStateError extends Error {
11
+ constructor(message) {
12
+ super(message);
13
+ this.name = "ModelPickerStateError";
14
+ }
15
+ }
16
+ export function modelReferenceKey(reference) {
17
+ return `${reference.provider}\0${reference.modelId}`;
18
+ }
19
+ export function modelReferencesEqual(left, right) {
20
+ return (left !== undefined && right !== undefined && left.provider === right.provider && left.modelId === right.modelId);
21
+ }
22
+ export function emptyModelPickerState() {
23
+ return {
24
+ schemaVersion: MODEL_PICKER_SCHEMA_VERSION,
25
+ favorites: [],
26
+ defaults: { projects: {} },
27
+ recents: { global: [], projects: {} },
28
+ };
29
+ }
30
+ function containsControlCharacter(value) {
31
+ return Array.from(value).some((character) => {
32
+ const codePoint = character.codePointAt(0) ?? 0;
33
+ return codePoint <= 0x1f || (codePoint >= 0x7f && codePoint <= 0x9f);
34
+ });
35
+ }
36
+ function validIdentifier(value) {
37
+ return typeof value === "string" && value.length > 0 && value.length <= 512 && !containsControlCharacter(value);
38
+ }
39
+ function validTimestamp(value) {
40
+ return typeof value === "string" && Number.isFinite(Date.parse(value));
41
+ }
42
+ function assertValidReference(reference) {
43
+ if (!validIdentifier(reference.provider) || !validIdentifier(reference.modelId)) {
44
+ throw new ModelPickerStateError("model reference requires bounded provider and modelId strings");
45
+ }
46
+ }
47
+ function parseReference(value) {
48
+ if (!value || typeof value !== "object")
49
+ throw new ModelPickerStateError("model reference must be an object");
50
+ const record = value;
51
+ if (!validIdentifier(record.provider) || !validIdentifier(record.modelId)) {
52
+ throw new ModelPickerStateError("model reference requires bounded provider and modelId strings");
53
+ }
54
+ return { provider: record.provider, modelId: record.modelId };
55
+ }
56
+ function parseRecent(value) {
57
+ const reference = parseReference(value);
58
+ const record = value;
59
+ if (!validTimestamp(record.lastUsedAt) || !Number.isInteger(record.useCount) || Number(record.useCount) < 1) {
60
+ throw new ModelPickerStateError("recent record has invalid timestamp or use count");
61
+ }
62
+ return { ...reference, lastUsedAt: record.lastUsedAt, useCount: Number(record.useCount) };
63
+ }
64
+ function parseState(value) {
65
+ if (!value || typeof value !== "object")
66
+ throw new ModelPickerStateError("state must be an object");
67
+ const record = value;
68
+ if (record.schemaVersion !== 1 && record.schemaVersion !== MODEL_PICKER_SCHEMA_VERSION) {
69
+ throw new ModelPickerStateError(`unsupported model picker state schema: ${String(record.schemaVersion)}`);
70
+ }
71
+ if (!Array.isArray(record.favorites))
72
+ throw new ModelPickerStateError("favorites must be an array");
73
+ if (!record.recents || typeof record.recents !== "object" || !Array.isArray(record.recents.global)) {
74
+ throw new ModelPickerStateError("recents must contain a global array");
75
+ }
76
+ if (!record.recents.projects ||
77
+ typeof record.recents.projects !== "object" ||
78
+ Array.isArray(record.recents.projects)) {
79
+ throw new ModelPickerStateError("project recents must be an object");
80
+ }
81
+ const favorites = record.favorites.map((value) => {
82
+ const reference = parseReference(value);
83
+ const favorite = value;
84
+ if (favorite.scope !== "global" && favorite.scope !== "project") {
85
+ throw new ModelPickerStateError("favorite scope must be global or project");
86
+ }
87
+ if (!validTimestamp(favorite.addedAt))
88
+ throw new ModelPickerStateError("favorite timestamp is invalid");
89
+ if (favorite.scope === "project" && !validIdentifier(favorite.projectKey)) {
90
+ throw new ModelPickerStateError("project favorite requires a project key");
91
+ }
92
+ return {
93
+ ...reference,
94
+ scope: favorite.scope,
95
+ ...(favorite.scope === "project" ? { projectKey: favorite.projectKey } : {}),
96
+ addedAt: favorite.addedAt,
97
+ };
98
+ });
99
+ const defaults = {};
100
+ if (record.defaults !== undefined) {
101
+ if (!record.defaults ||
102
+ typeof record.defaults !== "object" ||
103
+ !record.defaults.projects ||
104
+ typeof record.defaults.projects !== "object" ||
105
+ Array.isArray(record.defaults.projects)) {
106
+ throw new ModelPickerStateError("defaults must contain a projects object");
107
+ }
108
+ for (const [projectKey, reference] of Object.entries(record.defaults.projects)) {
109
+ if (!validIdentifier(projectKey))
110
+ throw new ModelPickerStateError("project default key is invalid");
111
+ defaults[projectKey] = parseReference(reference);
112
+ }
113
+ }
114
+ const projects = {};
115
+ for (const [projectKey, values] of Object.entries(record.recents.projects)) {
116
+ if (!validIdentifier(projectKey) || !Array.isArray(values)) {
117
+ throw new ModelPickerStateError("project recents contain an invalid key or value");
118
+ }
119
+ projects[projectKey] = values.map(parseRecent).slice(0, MODEL_PICKER_RECENT_LIMIT);
120
+ }
121
+ return {
122
+ schemaVersion: MODEL_PICKER_SCHEMA_VERSION,
123
+ favorites,
124
+ defaults: { projects: defaults },
125
+ recents: {
126
+ global: record.recents.global.map(parseRecent).slice(0, MODEL_PICKER_RECENT_LIMIT),
127
+ projects,
128
+ },
129
+ };
130
+ }
131
+ function statePath(paths) {
132
+ return join(paths.stateDir, "model-picker.json");
133
+ }
134
+ function lockPath(paths) {
135
+ return join(paths.stateDir, "model-picker.lock");
136
+ }
137
+ function quarantineSuffix(now) {
138
+ return now.toISOString().replace(/[^0-9]/g, "");
139
+ }
140
+ export function loadModelPickerState(paths, options = {}) {
141
+ const path = statePath(paths);
142
+ if (!existsSync(path))
143
+ return { state: emptyModelPickerState() };
144
+ try {
145
+ const metadata = lstatSync(path);
146
+ if (!metadata.isFile() || metadata.isSymbolicLink()) {
147
+ throw new ModelPickerStateError(`model picker state must be a regular file: ${path}`);
148
+ }
149
+ return { state: parseState(JSON.parse(readFileSync(path, "utf8"))) };
150
+ }
151
+ catch (error) {
152
+ if (error instanceof ModelPickerStateError && /regular file/.test(error.message))
153
+ throw error;
154
+ const message = error instanceof Error ? error.message : String(error);
155
+ if (options.recover === false)
156
+ throw new ModelPickerStateError(`model picker state is unreadable: ${message}`);
157
+ ensurePrivateDirectory(paths.stateDir);
158
+ const quarantinePath = join(paths.stateDir, `model-picker.corrupt-${quarantineSuffix(options.now ?? new Date())}.json`);
159
+ renameSync(path, quarantinePath);
160
+ return {
161
+ state: emptyModelPickerState(),
162
+ warning: `Unreadable model picker state was preserved at ${quarantinePath}`,
163
+ quarantinePath,
164
+ };
165
+ }
166
+ }
167
+ function updateRecent(records, reference, now) {
168
+ const existing = records.find((record) => modelReferencesEqual(record, reference));
169
+ return [
170
+ { ...reference, lastUsedAt: now.toISOString(), useCount: (existing?.useCount ?? 0) + 1 },
171
+ ...records.filter((record) => !modelReferencesEqual(record, reference)),
172
+ ].slice(0, MODEL_PICKER_RECENT_LIMIT);
173
+ }
174
+ export class ModelPickerStore {
175
+ paths;
176
+ constructor(paths) {
177
+ this.paths = paths;
178
+ }
179
+ load(options = {}) {
180
+ return loadModelPickerState(this.paths, options);
181
+ }
182
+ mutate(mutator, now) {
183
+ const release = acquireStateLock({
184
+ path: lockPath(this.paths),
185
+ describe: "model picker state",
186
+ now,
187
+ onBusy: (inspection) => new ModelPickerStateError(`model picker state is busy (${inspection.status})`),
188
+ });
189
+ try {
190
+ const state = this.load({ now }).state;
191
+ mutator(state);
192
+ writeFilePrivateAtomic(statePath(this.paths), `${JSON.stringify(state, null, 2)}\n`, this.paths.stateDir);
193
+ return state;
194
+ }
195
+ finally {
196
+ release();
197
+ }
198
+ }
199
+ setProjectDefault(reference, projectKey, now = new Date()) {
200
+ assertValidReference(reference);
201
+ if (!validIdentifier(projectKey))
202
+ throw new ModelPickerStateError("project key is invalid");
203
+ return this.mutate((state) => {
204
+ state.defaults.projects[projectKey] = { ...reference };
205
+ }, now);
206
+ }
207
+ recordDispatch(reference, projectKey, now = new Date()) {
208
+ assertValidReference(reference);
209
+ if (!validIdentifier(projectKey))
210
+ throw new ModelPickerStateError("project key is invalid");
211
+ return this.mutate((state) => {
212
+ state.recents.global = updateRecent(state.recents.global, reference, now);
213
+ state.recents.projects[projectKey] = updateRecent(state.recents.projects[projectKey] ?? [], reference, now);
214
+ }, now);
215
+ }
216
+ toggleFavorite(reference, scope, projectKey, now = new Date()) {
217
+ assertValidReference(reference);
218
+ if (scope === "project" && !validIdentifier(projectKey)) {
219
+ throw new ModelPickerStateError("project favorite requires a project key");
220
+ }
221
+ return this.mutate((state) => {
222
+ const matchesScope = (favorite) => favorite.scope === scope && (scope === "global" || favorite.projectKey === projectKey);
223
+ const existing = state.favorites.find((favorite) => matchesScope(favorite) && modelReferencesEqual(favorite, reference));
224
+ if (existing) {
225
+ state.favorites = state.favorites.filter((favorite) => favorite !== existing);
226
+ return;
227
+ }
228
+ state.favorites.push({
229
+ ...reference,
230
+ scope,
231
+ ...(scope === "project" ? { projectKey } : {}),
232
+ addedAt: now.toISOString(),
233
+ });
234
+ }, now);
235
+ }
236
+ clearRecents(scope, projectKey, now = new Date()) {
237
+ return this.mutate((state) => {
238
+ if (scope === "global" || scope === "all")
239
+ state.recents.global = [];
240
+ if (scope === "all")
241
+ state.recents.projects = {};
242
+ if (scope === "project" && projectKey)
243
+ delete state.recents.projects[projectKey];
244
+ }, now);
245
+ }
246
+ }
247
+ function hashProjectIdentity(kind, value) {
248
+ return createHash("sha256").update(`jouzu-project-v1\0${kind}\0${value}`).digest("hex");
249
+ }
250
+ export function deriveProjectKey(cwd, options = {}) {
251
+ const runGit = options.runGit ??
252
+ ((directory) => {
253
+ const result = spawnSync("git", ["rev-parse", "--git-common-dir"], {
254
+ cwd: directory,
255
+ encoding: "utf8",
256
+ timeout: 2_000,
257
+ });
258
+ return result.status === 0 ? result.stdout.trim() || undefined : undefined;
259
+ });
260
+ const resolveRealpath = options.realpath ?? ((path) => realpathSync.native(path));
261
+ const gitCommonDir = runGit(cwd);
262
+ if (gitCommonDir) {
263
+ const absolute = isAbsolute(gitCommonDir) ? gitCommonDir : resolve(cwd, gitCommonDir);
264
+ return hashProjectIdentity("git", resolveRealpath(absolute));
265
+ }
266
+ return hashProjectIdentity("cwd", resolveRealpath(cwd));
267
+ }
268
+ const PROJECT_DEFAULT_BYPASS_FLAGS = new Set(["--continue", "-c", "--resume", "-r", "--session", "--session-id"]);
269
+ export function projectDefaultAppliesAtStartup(args) {
270
+ for (const argument of args) {
271
+ if (argument === "--model" ||
272
+ argument.startsWith("--model=") ||
273
+ argument === "--models" ||
274
+ argument.startsWith("--models=") ||
275
+ argument === "--provider" ||
276
+ argument.startsWith("--provider=") ||
277
+ PROJECT_DEFAULT_BYPASS_FLAGS.has(argument) ||
278
+ argument.startsWith("--session=") ||
279
+ argument.startsWith("--session-id=")) {
280
+ return false;
281
+ }
282
+ }
283
+ return true;
284
+ }
285
+ export function previousModelStack(entries, current, limit = MODEL_PICKER_HISTORY_LIMIT) {
286
+ const sequence = [];
287
+ for (const entry of entries) {
288
+ if (!entry || typeof entry !== "object")
289
+ continue;
290
+ const value = entry;
291
+ let reference;
292
+ if (value.type === "model_change" && validIdentifier(value.provider) && validIdentifier(value.modelId)) {
293
+ reference = { provider: value.provider, modelId: value.modelId };
294
+ }
295
+ else if (value.type === "message" &&
296
+ value.message?.role === "assistant" &&
297
+ validIdentifier(value.message.provider) &&
298
+ validIdentifier(value.message.model)) {
299
+ reference = { provider: value.message.provider, modelId: value.message.model };
300
+ }
301
+ if (reference && !modelReferencesEqual(sequence.at(-1), reference))
302
+ sequence.push(reference);
303
+ }
304
+ if (modelReferencesEqual(sequence.at(-1), current))
305
+ sequence.pop();
306
+ const seen = new Set();
307
+ const result = [];
308
+ for (const reference of sequence.reverse()) {
309
+ const key = modelReferenceKey(reference);
310
+ if (seen.has(key) || modelReferencesEqual(reference, current))
311
+ continue;
312
+ seen.add(key);
313
+ result.push(reference);
314
+ if (result.length >= Math.max(0, limit))
315
+ break;
316
+ }
317
+ return result;
318
+ }
319
+ //# sourceMappingURL=model-picker-state.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"model-picker-state.js","sourceRoot":"","sources":["../src/model-picker-state.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,65 @@
1
+ import type { InlineExtension } from "@earendil-works/pi-coding-agent";
2
+ import { type Focusable } from "@earendil-works/pi-tui";
3
+ import { type PickerFilter, type PickerRow } from "./model-picker-ranking.js";
4
+ import { type PaletteComponent, type PaletteComponentContext, type PaletteRoute } from "./palette.js";
5
+ import type { JouzuPaths } from "./paths.js";
6
+ export interface JouzuModelPickerRequest {
7
+ source: "action" | "command";
8
+ initialSearchInput?: string;
9
+ }
10
+ export interface JouzuModelPickerOptions {
11
+ applyProjectDefaultAtStartup?: boolean;
12
+ }
13
+ export interface ModelPickerComponentOptions {
14
+ context: PaletteComponentContext;
15
+ initialRoute: PaletteRoute;
16
+ getRows(query: string, filter: PickerFilter): PickerRow[];
17
+ onSelect(row: PickerRow, scope: "session" | "project"): Promise<void>;
18
+ onToggleFavorite(row: PickerRow, scope: "project" | "global"): void;
19
+ }
20
+ export declare class ModelPickerComponent implements PaletteComponent, Focusable {
21
+ private readonly tui;
22
+ private readonly theme;
23
+ private readonly keybindings;
24
+ private readonly styles;
25
+ private readonly wordmark;
26
+ private readonly close;
27
+ private readonly getRows;
28
+ private readonly onSelect;
29
+ private readonly onToggleFavorite;
30
+ private readonly searchInput;
31
+ private rows;
32
+ private filter;
33
+ private filterCounts;
34
+ private selectedIndex;
35
+ private busy;
36
+ private message?;
37
+ private disposed;
38
+ private _focused;
39
+ constructor(options: ModelPickerComponentOptions);
40
+ get focused(): boolean;
41
+ set focused(value: boolean);
42
+ route(route: PaletteRoute): void;
43
+ /**
44
+ * Filter counts describe the unfiltered inventory, so they change only when
45
+ * picker state does. Recomputing them per keystroke would trigger three extra
46
+ * full ranking passes for a result that cannot have changed.
47
+ */
48
+ private recomputeFilterCounts;
49
+ private recomputeRows;
50
+ private moveSelection;
51
+ private cycleFilter;
52
+ private runSelection;
53
+ private toggleFavorite;
54
+ handleInput(data: string): void;
55
+ private rowText;
56
+ render(width: number): string[];
57
+ invalidate(): void;
58
+ dispose(): void;
59
+ }
60
+ export interface JouzuModelPickerIntegration {
61
+ extension: InlineExtension;
62
+ open(request: JouzuModelPickerRequest): Promise<boolean>;
63
+ }
64
+ export declare function createJouzuModelPicker(paths: JouzuPaths, options?: JouzuModelPickerOptions): JouzuModelPickerIntegration;
65
+ //# sourceMappingURL=model-picker.d.ts.map