acture-palette-react 1.0.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.
package/dist/index.js ADDED
@@ -0,0 +1,479 @@
1
+ import { Command } from 'cmdk';
2
+ import { useState, useEffect, useMemo } from 'react';
3
+ import { jsx, Fragment, jsxs } from 'react/jsx-runtime';
4
+
5
+ // src/palette.tsx
6
+ function useCommandsChanged(registry) {
7
+ const [revision, setRevision] = useState(0);
8
+ useEffect(() => {
9
+ return registry.onCommandsChanged(() => setRevision((n) => n + 1));
10
+ }, [registry]);
11
+ return revision;
12
+ }
13
+
14
+ // src/derive-kind.ts
15
+ function summarizeParams(record) {
16
+ const schema = record.params;
17
+ if (schema === void 0) return [];
18
+ const shape = readObjectShape(schema);
19
+ if (shape === null) {
20
+ return [
21
+ {
22
+ name: "_",
23
+ schema,
24
+ isPicker: isPickerSchema(schema),
25
+ hasDefault: hasDefaultValue(schema),
26
+ optional: isOptional(schema)
27
+ }
28
+ ];
29
+ }
30
+ return Object.entries(shape).map(([name, fieldSchema]) => ({
31
+ name,
32
+ schema: fieldSchema,
33
+ isPicker: isPickerSchema(fieldSchema),
34
+ hasDefault: hasDefaultValue(fieldSchema),
35
+ optional: isOptional(fieldSchema)
36
+ }));
37
+ }
38
+ function deriveKind(record) {
39
+ if (record.kind !== void 0) return record.kind;
40
+ const summary = summarizeParams(record);
41
+ if (summary.length === 0) return "atomic";
42
+ const allPicker = summary.every((p) => p.isPicker);
43
+ if (summary.length <= 2 && allPicker) return "atomic";
44
+ if (summary.length === 3 && allPicker && summary.every((p) => p.hasDefault)) return "atomic";
45
+ return "handoff";
46
+ }
47
+ function readObjectShape(s) {
48
+ const shape = s.shape;
49
+ if (shape && typeof shape === "object") return shape;
50
+ return null;
51
+ }
52
+ function readDef(s) {
53
+ if (s === null || typeof s !== "object") return {};
54
+ const def = s._def ?? s.def ?? {};
55
+ return def;
56
+ }
57
+ function getTypeName(s) {
58
+ const def = readDef(s);
59
+ if (typeof def.typeName === "string") return def.typeName;
60
+ if (typeof def.type === "string") return def.type;
61
+ const ctor = s.constructor;
62
+ return ctor?.name;
63
+ }
64
+ function isPickerSchema(s) {
65
+ if (s === null || typeof s !== "object") return false;
66
+ const inner = unwrap(s);
67
+ const t = getTypeName(inner);
68
+ if (!t) return false;
69
+ if (t === "ZodEnum" || t === "enum") return true;
70
+ if (t === "ZodBoolean" || t === "boolean") return true;
71
+ if (t === "ZodNativeEnum" || t === "nativeEnum") return true;
72
+ if (t === "ZodLiteral" || t === "literal") return true;
73
+ const meta = readMeta(inner);
74
+ if (meta && (meta["paramKind"] === "picker" || meta["picker"] === true)) {
75
+ return true;
76
+ }
77
+ return false;
78
+ }
79
+ function hasDefaultValue(s) {
80
+ const t = getTypeName(s);
81
+ if (t === "ZodDefault" || t === "default") return true;
82
+ let cur = s;
83
+ for (let i = 0; i < 4 && cur !== void 0 && cur !== null; i++) {
84
+ const def = readDef(cur);
85
+ if ("defaultValue" in def) return true;
86
+ cur = def.innerType;
87
+ }
88
+ return false;
89
+ }
90
+ function isOptional(s) {
91
+ const t = getTypeName(s);
92
+ return t === "ZodOptional" || t === "optional" || hasDefaultValue(s);
93
+ }
94
+ function readMeta(s) {
95
+ if (s === null || typeof s !== "object") return null;
96
+ const def = readDef(s);
97
+ if (def["description"] && typeof def["description"] === "object") {
98
+ return def["description"];
99
+ }
100
+ return null;
101
+ }
102
+ function unwrap(s) {
103
+ let cur = s;
104
+ for (let i = 0; i < 6; i++) {
105
+ if (cur === null || typeof cur !== "object") break;
106
+ const t = getTypeName(cur);
107
+ if (t !== "ZodOptional" && t !== "optional" && t !== "ZodDefault" && t !== "default" && t !== "ZodNullable" && t !== "nullable" && t !== "ZodBranded" && t !== "branded") {
108
+ break;
109
+ }
110
+ const def = readDef(cur);
111
+ const inner = def.innerType;
112
+ if (inner === void 0) break;
113
+ cur = inner;
114
+ }
115
+ return cur;
116
+ }
117
+ function readEnumOptions(s) {
118
+ const inner = unwrap(s);
119
+ const def = readDef(inner);
120
+ if (Array.isArray(def.values)) {
121
+ return def.values.filter((v) => typeof v === "string");
122
+ }
123
+ if (def.entries && typeof def.entries === "object") {
124
+ return Object.keys(def.entries);
125
+ }
126
+ return [];
127
+ }
128
+ function PickerChain(props) {
129
+ const { command, defaults, onSubmit, onCancel } = props;
130
+ const summary = summarizeParams(command);
131
+ const [values, setValues] = useState(() => ({ ...defaults ?? {} }));
132
+ const [step, setStep] = useState(0);
133
+ const current = summary[step];
134
+ function commit(value) {
135
+ if (!current) return;
136
+ const next = { ...values, [current.name]: value };
137
+ setValues(next);
138
+ if (step + 1 >= summary.length) {
139
+ onSubmit(next);
140
+ } else {
141
+ setStep(step + 1);
142
+ }
143
+ }
144
+ function back() {
145
+ if (step === 0) {
146
+ onCancel();
147
+ return;
148
+ }
149
+ setStep(step - 1);
150
+ }
151
+ if (!current) {
152
+ onSubmit(values);
153
+ return /* @__PURE__ */ jsx(Fragment, {});
154
+ }
155
+ const counter = summary.length >= 2 ? `${step + 1}/${summary.length}` : null;
156
+ const label = paramLabel(current);
157
+ return /* @__PURE__ */ jsxs("div", { "data-acture-picker-chain": true, style: { display: "flex", flexDirection: "column" }, children: [
158
+ /* @__PURE__ */ jsxs(
159
+ "div",
160
+ {
161
+ "data-acture-picker-chain-header": true,
162
+ style: { padding: "8px 12px", borderBottom: "1px solid var(--acture-divider, #eee)" },
163
+ children: [
164
+ /* @__PURE__ */ jsx("strong", { children: command.title }),
165
+ counter ? /* @__PURE__ */ jsx("span", { style: { marginLeft: 8, opacity: 0.6 }, children: counter }) : null,
166
+ /* @__PURE__ */ jsxs("span", { style: { marginLeft: 8, opacity: 0.6 }, children: [
167
+ "\xB7 ",
168
+ label
169
+ ] })
170
+ ]
171
+ }
172
+ ),
173
+ /* @__PURE__ */ jsx(Step, { param: current, initial: values[current.name], onCommit: commit, onBack: back }, `${command.id}.${current.name}`),
174
+ /* @__PURE__ */ jsxs("div", { style: { padding: "4px 12px", opacity: 0.6, fontSize: "0.85em" }, children: [
175
+ "\u23CE to advance \xB7 Esc to ",
176
+ step === 0 ? "cancel" : "go back"
177
+ ] })
178
+ ] });
179
+ }
180
+ function paramLabel(p) {
181
+ const def = p.schema.description;
182
+ if (typeof def === "string" && def.length > 0) return def;
183
+ return p.name;
184
+ }
185
+ function Step(props) {
186
+ const { param } = props;
187
+ if (param.isPicker) {
188
+ const enumOptions = readEnumOptions(param.schema);
189
+ if (enumOptions.length > 0) {
190
+ return /* @__PURE__ */ jsx(EnumPicker, { ...props, options: enumOptions });
191
+ }
192
+ const innerName = unwrap(param.schema);
193
+ const t = innerName._def?.typeName ?? innerName.def?.type;
194
+ if (t === "ZodBoolean" || t === "boolean") {
195
+ return /* @__PURE__ */ jsx(EnumPicker, { ...props, options: ["true", "false"], coerce: (s) => s === "true" });
196
+ }
197
+ }
198
+ return /* @__PURE__ */ jsx(TextStep, { ...props });
199
+ }
200
+ function EnumPicker({
201
+ param,
202
+ initial,
203
+ onCommit,
204
+ onBack,
205
+ options,
206
+ coerce
207
+ }) {
208
+ return /* @__PURE__ */ jsxs(Command, { label: `Pick ${param.name}`, shouldFilter: true, children: [
209
+ /* @__PURE__ */ jsx(
210
+ Command.Input,
211
+ {
212
+ placeholder: `Pick ${param.name}\u2026`,
213
+ autoFocus: true,
214
+ defaultValue: typeof initial === "string" ? initial : "",
215
+ onKeyDown: (e) => {
216
+ if (e.key === "Escape") {
217
+ e.preventDefault();
218
+ onBack();
219
+ }
220
+ }
221
+ }
222
+ ),
223
+ /* @__PURE__ */ jsxs(Command.List, { children: [
224
+ /* @__PURE__ */ jsx(Command.Empty, { children: "No match." }),
225
+ options.map((opt) => /* @__PURE__ */ jsx(
226
+ Command.Item,
227
+ {
228
+ value: opt,
229
+ onSelect: () => onCommit(coerce ? coerce(opt) : opt),
230
+ children: opt
231
+ },
232
+ opt
233
+ ))
234
+ ] })
235
+ ] });
236
+ }
237
+ function TextStep({ param, initial, onCommit, onBack }) {
238
+ const [draft, setDraft] = useState(
239
+ typeof initial === "string" ? initial : initial === void 0 ? "" : String(initial)
240
+ );
241
+ const [errorMsg, setErrorMsg] = useState(null);
242
+ function submit() {
243
+ const coerced = coerceFromText(draft, param);
244
+ const parseResult = param.schema.safeParse(coerced);
245
+ if (!parseResult.success) {
246
+ setErrorMsg(parseResult.error?.issues?.[0]?.message ?? "Invalid value");
247
+ return;
248
+ }
249
+ onCommit(parseResult.data);
250
+ }
251
+ return /* @__PURE__ */ jsxs("div", { style: { padding: 8, display: "flex", flexDirection: "column", gap: 4 }, children: [
252
+ /* @__PURE__ */ jsx(
253
+ "input",
254
+ {
255
+ "data-acture-text-step": true,
256
+ autoFocus: true,
257
+ value: draft,
258
+ placeholder: inferPlaceholder(param),
259
+ onChange: (e) => {
260
+ setDraft(e.target.value);
261
+ if (errorMsg) setErrorMsg(null);
262
+ },
263
+ onKeyDown: (e) => {
264
+ if (e.key === "Enter") {
265
+ e.preventDefault();
266
+ submit();
267
+ return;
268
+ }
269
+ if (e.key === "Escape") {
270
+ e.preventDefault();
271
+ onBack();
272
+ }
273
+ },
274
+ style: {
275
+ padding: "8px 10px",
276
+ border: errorMsg ? "1px solid #c33" : "1px solid var(--acture-divider, #ccc)",
277
+ borderRadius: 4,
278
+ font: "inherit"
279
+ }
280
+ }
281
+ ),
282
+ errorMsg ? /* @__PURE__ */ jsx("span", { style: { color: "#c33", fontSize: "0.85em" }, "data-acture-validation-error": true, children: errorMsg }) : null
283
+ ] });
284
+ }
285
+ function coerceFromText(raw, p) {
286
+ const inner = unwrap(p.schema);
287
+ const t = inner._def?.typeName ?? inner.def?.type;
288
+ if (t === "ZodNumber" || t === "number") {
289
+ const n = Number(raw);
290
+ return Number.isFinite(n) ? n : raw;
291
+ }
292
+ if (t === "ZodBoolean" || t === "boolean") {
293
+ return raw === "true";
294
+ }
295
+ return raw;
296
+ }
297
+ function inferPlaceholder(p) {
298
+ const inner = unwrap(p.schema);
299
+ const t = inner._def?.typeName ?? inner.def?.type;
300
+ if (t === "ZodNumber" || t === "number") return `${p.name} (number)\u2026`;
301
+ if (t === "ZodString" || t === "string") return `${p.name}\u2026`;
302
+ return `${p.name}\u2026`;
303
+ }
304
+ function CommandPalette(props) {
305
+ const {
306
+ registry,
307
+ context,
308
+ tiers,
309
+ onDispatched,
310
+ onParameterizedSelect,
311
+ formAdapter,
312
+ paramDefaults,
313
+ placeholder = "Type a command\u2026",
314
+ className,
315
+ renderItem
316
+ } = props;
317
+ const revision = useCommandsChanged(registry);
318
+ const [view, setView] = useState({ kind: "list" });
319
+ const groups = useMemo(() => {
320
+ const list = registry.list({
321
+ tiers: tiers ?? ["stable"],
322
+ ...context !== void 0 ? { context } : {}
323
+ });
324
+ return groupByCategory(list);
325
+ }, [registry, revision, tiers, context]);
326
+ async function dispatchCommand(cmd, params) {
327
+ const result = await registry.dispatch(cmd.id, params, context);
328
+ onDispatched?.(cmd, result);
329
+ setView({ kind: "list" });
330
+ }
331
+ function selectFromList(id) {
332
+ const cmd = registry.get(id);
333
+ if (!cmd) return;
334
+ if (cmd.params === void 0) {
335
+ void dispatchCommand(cmd);
336
+ return;
337
+ }
338
+ const defaults = paramDefaults?.(cmd);
339
+ const kind = deriveKind(cmd);
340
+ if (kind === "atomic") {
341
+ const next = defaults !== void 0 ? { kind: "pickerChain", cmd, defaults } : { kind: "pickerChain", cmd };
342
+ setView(next);
343
+ return;
344
+ }
345
+ if (formAdapter) {
346
+ const next = defaults !== void 0 ? { kind: "form", cmd, defaults } : { kind: "form", cmd };
347
+ setView(next);
348
+ return;
349
+ }
350
+ onParameterizedSelect?.(cmd);
351
+ }
352
+ if (view.kind === "pickerChain") {
353
+ const chainProps = view.defaults !== void 0 ? {
354
+ command: view.cmd,
355
+ defaults: view.defaults,
356
+ onSubmit: (params) => {
357
+ void dispatchCommand(view.cmd, params);
358
+ },
359
+ onCancel: () => setView({ kind: "list" })
360
+ } : {
361
+ command: view.cmd,
362
+ onSubmit: (params) => {
363
+ void dispatchCommand(view.cmd, params);
364
+ },
365
+ onCancel: () => setView({ kind: "list" })
366
+ };
367
+ return /* @__PURE__ */ jsx("div", { className, "data-acture-palette-view": "picker-chain", children: /* @__PURE__ */ jsx(PickerChain, { ...chainProps }) });
368
+ }
369
+ if (view.kind === "form" && formAdapter) {
370
+ const FormAdapter = formAdapter;
371
+ const formProps = view.defaults !== void 0 ? {
372
+ command: view.cmd,
373
+ defaults: view.defaults,
374
+ onSubmit: (params) => {
375
+ void dispatchCommand(view.cmd, params);
376
+ },
377
+ onCancel: () => setView({ kind: "list" })
378
+ } : {
379
+ command: view.cmd,
380
+ onSubmit: (params) => {
381
+ void dispatchCommand(view.cmd, params);
382
+ },
383
+ onCancel: () => setView({ kind: "list" })
384
+ };
385
+ return /* @__PURE__ */ jsx("div", { className, "data-acture-palette-view": "form", children: /* @__PURE__ */ jsx(FormAdapter, { ...formProps }) });
386
+ }
387
+ return /* @__PURE__ */ jsxs(Command, { className, label: "Command palette", "data-acture-palette-view": "list", children: [
388
+ /* @__PURE__ */ jsx(Command.Input, { placeholder, autoFocus: true }),
389
+ /* @__PURE__ */ jsxs(Command.List, { children: [
390
+ /* @__PURE__ */ jsx(Command.Empty, { children: "No matching commands." }),
391
+ groups.map(([category, items]) => /* @__PURE__ */ jsx(Command.Group, { heading: category, children: items.map((cmd) => /* @__PURE__ */ jsx(
392
+ Command.Item,
393
+ {
394
+ value: paletteValue(cmd),
395
+ keywords: cmd.aliases ? [...cmd.aliases] : void 0,
396
+ onSelect: () => selectFromList(cmd.id),
397
+ children: renderItem ? renderItem(cmd) : /* @__PURE__ */ jsx(DefaultItem, { cmd })
398
+ },
399
+ cmd.id
400
+ )) }, category))
401
+ ] })
402
+ ] });
403
+ }
404
+ function DefaultItem({ cmd }) {
405
+ const isParameterized = cmd.params !== void 0;
406
+ const kind = isParameterized ? deriveKind(cmd) : null;
407
+ const keybinding = formatKeybinding(cmd.keybinding);
408
+ return /* @__PURE__ */ jsxs(
409
+ "span",
410
+ {
411
+ "data-acture-palette-item": true,
412
+ "data-acture-parameterized": isParameterized ? "" : void 0,
413
+ "data-acture-kind": kind ?? void 0,
414
+ style: { display: "flex", alignItems: "center", justifyContent: "space-between", gap: 8, flex: 1 },
415
+ children: [
416
+ /* @__PURE__ */ jsxs("span", { style: { display: "flex", alignItems: "center", gap: 6 }, children: [
417
+ cmd.icon ? /* @__PURE__ */ jsx("span", { "aria-hidden": "true", children: cmd.icon }) : null,
418
+ /* @__PURE__ */ jsx("span", { children: cmd.title }),
419
+ isParameterized ? /* @__PURE__ */ jsx(
420
+ "span",
421
+ {
422
+ "data-acture-kind-badge": true,
423
+ style: {
424
+ fontSize: "0.7em",
425
+ opacity: 0.6,
426
+ padding: "0 4px",
427
+ border: "1px solid currentColor",
428
+ borderRadius: 4
429
+ },
430
+ children: kind === "atomic" ? "\u21E5" : "\u2026"
431
+ }
432
+ ) : null
433
+ ] }),
434
+ keybinding ? /* @__PURE__ */ jsx("kbd", { style: { fontSize: "0.85em", opacity: 0.7 }, children: keybinding }) : null
435
+ ]
436
+ }
437
+ );
438
+ }
439
+ function paletteValue(cmd) {
440
+ const parts = [cmd.title, cmd.id];
441
+ if (cmd.aliases) parts.push(...cmd.aliases);
442
+ if (cmd.category) parts.push(cmd.category);
443
+ return parts.join(" ");
444
+ }
445
+ function formatKeybinding(kb) {
446
+ if (kb === void 0) return null;
447
+ if (typeof kb === "string") return kb;
448
+ if (kb.length === 0) return null;
449
+ return kb[0] ?? null;
450
+ }
451
+ function groupByCategory(list) {
452
+ const groups = /* @__PURE__ */ new Map();
453
+ const ordered = [];
454
+ for (const cmd of list) {
455
+ const category = cmd.category ?? "Commands";
456
+ if (!groups.has(category)) {
457
+ groups.set(category, []);
458
+ ordered.push(category);
459
+ }
460
+ groups.get(category).push(cmd);
461
+ }
462
+ for (const items of groups.values()) {
463
+ items.sort((a, b) => {
464
+ const sa = scoreOf(a);
465
+ const sb = scoreOf(b);
466
+ if (sa !== sb) return sb - sa;
467
+ return a.title.localeCompare(b.title);
468
+ });
469
+ }
470
+ return ordered.map((cat) => [cat, groups.get(cat)]);
471
+ }
472
+ function scoreOf(cmd) {
473
+ if (typeof cmd.defaultScore === "number") return cmd.defaultScore;
474
+ return 0;
475
+ }
476
+
477
+ export { CommandPalette, PickerChain, deriveKind, isPickerSchema, readEnumOptions, summarizeParams, useCommandsChanged };
478
+ //# sourceMappingURL=index.js.map
479
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/use-commands-changed.ts","../src/derive-kind.ts","../src/picker-chain.tsx","../src/palette.tsx"],"names":["useState","jsx","jsxs","Command"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * Subscribe to a registry's `commandsChanged` event from inside React.\n *\n * Returns a monotonically-incrementing `revision` integer that changes\n * whenever a command is added or removed. Useful as a key for\n * `useMemo` over the command list.\n */\n\nimport { useEffect, useState } from 'react';\nimport type { Registry } from 'acture';\n\nexport function useCommandsChanged(registry: Registry): number {\n const [revision, setRevision] = useState(0);\n useEffect(() => {\n return registry.onCommandsChanged(() => setRevision((n) => n + 1));\n }, [registry]);\n return revision;\n}\n","/**\n * Auto-derived `kind` heuristic per research-2 §9.3 (acture-palette-design\n * skill). Determines whether a parameterized command should be collected\n * inline (atomic picker chain) or handed off to a dedicated form.\n *\n * 0 params → atomic\n * 1–2 params, all picker-typed → atomic\n * 3 params, all picker-typed AND all have defaults → atomic\n * else → handoff\n *\n * \"Picker-typed\" = the param has a discrete, enumerable value space\n * (enum, boolean) OR is a string carrying an explicit `paramKind: 'picker'`\n * extension hint via `.describe()`. Unconstrained `z.string()` and\n * `z.number()` are NOT picker-typed.\n *\n * Authors override by setting `kind` explicitly on the CommandRecord.\n */\n\nimport type { AnyCommandRecord, CommandKind } from 'acture';\nimport type { z } from 'zod';\n\nexport interface ParamSummary {\n readonly name: string;\n readonly schema: z.ZodTypeAny;\n readonly isPicker: boolean;\n readonly hasDefault: boolean;\n readonly optional: boolean;\n}\n\n/** Inspect a Zod schema and produce per-field summaries for deriveKind\n * and the picker-chain renderer. Defensive against non-object schemas. */\nexport function summarizeParams(record: AnyCommandRecord): ParamSummary[] {\n const schema = record.params;\n if (schema === undefined) return [];\n // Zod v4: z.object exposes `.shape`. Other types (z.string, z.enum at\n // root) are degenerate single-field params — treat as one anonymous\n // field. The dispatcher passes the raw value through in that case.\n const shape = readObjectShape(schema as unknown as { shape?: unknown });\n if (shape === null) {\n return [\n {\n name: '_',\n schema: schema as unknown as z.ZodTypeAny,\n isPicker: isPickerSchema(schema as unknown as z.ZodTypeAny),\n hasDefault: hasDefaultValue(schema as unknown as z.ZodTypeAny),\n optional: isOptional(schema as unknown as z.ZodTypeAny),\n },\n ];\n }\n return Object.entries(shape).map(([name, fieldSchema]) => ({\n name,\n schema: fieldSchema as z.ZodTypeAny,\n isPicker: isPickerSchema(fieldSchema as z.ZodTypeAny),\n hasDefault: hasDefaultValue(fieldSchema as z.ZodTypeAny),\n optional: isOptional(fieldSchema as z.ZodTypeAny),\n }));\n}\n\n/** Auto-derive `kind` from the param summary; explicit `kind` wins. */\nexport function deriveKind(record: AnyCommandRecord): CommandKind {\n if (record.kind !== undefined) return record.kind;\n const summary = summarizeParams(record);\n if (summary.length === 0) return 'atomic';\n const allPicker = summary.every((p) => p.isPicker);\n if (summary.length <= 2 && allPicker) return 'atomic';\n if (summary.length === 3 && allPicker && summary.every((p) => p.hasDefault)) return 'atomic';\n return 'handoff';\n}\n\n/* ───────────────────────── Zod inspection ─────────────────────────── */\n\nfunction readObjectShape(s: { shape?: unknown }): Record<string, unknown> | null {\n const shape = s.shape;\n if (shape && typeof shape === 'object') return shape as Record<string, unknown>;\n return null;\n}\n\nfunction readDef(s: unknown): { typeName?: string; type?: string } & Record<string, unknown> {\n if (s === null || typeof s !== 'object') return {};\n const def = (s as { _def?: object; def?: object })._def ?? (s as { def?: object }).def ?? {};\n return def as Record<string, unknown>;\n}\n\nfunction getTypeName(s: unknown): string | undefined {\n const def = readDef(s);\n // Zod v3 used _def.typeName ('ZodString'). Zod v4 uses .def.type ('string').\n if (typeof def.typeName === 'string') return def.typeName;\n if (typeof def.type === 'string') return def.type;\n // Last resort: constructor name.\n const ctor = (s as { constructor?: { name?: string } }).constructor;\n return ctor?.name;\n}\n\n/** Picker-typed = discrete, enumerable value space. */\nexport function isPickerSchema(s: z.ZodTypeAny): boolean {\n if (s === null || typeof s !== 'object') return false;\n // Unwrap optional/default/nullable shells.\n const inner = unwrap(s);\n const t = getTypeName(inner);\n if (!t) return false;\n if (t === 'ZodEnum' || t === 'enum') return true;\n if (t === 'ZodBoolean' || t === 'boolean') return true;\n if (t === 'ZodNativeEnum' || t === 'nativeEnum') return true;\n if (t === 'ZodLiteral' || t === 'literal') return true;\n // Honor an explicit author hint placed in `.describe()` or `.meta()`.\n const meta = readMeta(inner);\n if (meta && (meta['paramKind'] === 'picker' || meta['picker'] === true)) {\n return true;\n }\n return false;\n}\n\n/** Has the field declared a default value? Drives the 3-param atomic\n * exception. */\nexport function hasDefaultValue(s: z.ZodTypeAny): boolean {\n const t = getTypeName(s);\n if (t === 'ZodDefault' || t === 'default') return true;\n // Zod v4: an inner `.def.defaultValue` lives on the wrapper. Walk the\n // unwrap chain looking for one.\n let cur: unknown = s;\n for (let i = 0; i < 4 && cur !== undefined && cur !== null; i++) {\n const def = readDef(cur);\n if ('defaultValue' in def) return true;\n cur = (def as { innerType?: unknown }).innerType;\n }\n return false;\n}\n\nexport function isOptional(s: z.ZodTypeAny): boolean {\n const t = getTypeName(s);\n return t === 'ZodOptional' || t === 'optional' || hasDefaultValue(s);\n}\n\n/** Read `.describe()` / `.meta()` payload, if any. */\nfunction readMeta(s: unknown): Record<string, unknown> | null {\n if (s === null || typeof s !== 'object') return null;\n const def = readDef(s);\n if (def['description'] && typeof def['description'] === 'object') {\n return def['description'] as Record<string, unknown>;\n }\n return null;\n}\n\n/** Unwrap optional/default/nullable/branded shells to the inner type. */\nexport function unwrap(s: z.ZodTypeAny): z.ZodTypeAny {\n let cur: unknown = s;\n for (let i = 0; i < 6; i++) {\n if (cur === null || typeof cur !== 'object') break;\n const t = getTypeName(cur);\n if (\n t !== 'ZodOptional' &&\n t !== 'optional' &&\n t !== 'ZodDefault' &&\n t !== 'default' &&\n t !== 'ZodNullable' &&\n t !== 'nullable' &&\n t !== 'ZodBranded' &&\n t !== 'branded'\n ) {\n break;\n }\n const def = readDef(cur);\n const inner = (def as { innerType?: unknown }).innerType;\n if (inner === undefined) break;\n cur = inner;\n }\n return cur as z.ZodTypeAny;\n}\n\n/** Read enum options for picker rendering. Returns [] for non-enums. */\nexport function readEnumOptions(s: z.ZodTypeAny): string[] {\n const inner = unwrap(s);\n const def = readDef(inner);\n // Zod v4: enum stores values on `.entries` (object) or `.values` (array).\n if (Array.isArray((def as { values?: unknown }).values)) {\n return ((def as { values: unknown[] }).values as unknown[])\n .filter((v): v is string => typeof v === 'string');\n }\n if ((def as { entries?: unknown }).entries && typeof (def as { entries?: unknown }).entries === 'object') {\n return Object.keys((def as { entries: Record<string, unknown> }).entries);\n }\n return [];\n}\n","/**\n * Atomic picker-chain UI rendered INSIDE the palette container.\n *\n * Used when `deriveKind(record) === 'atomic'` for parameterized\n * commands. Each step shows a labeled picker / input for one param;\n * Enter advances when valid; Esc backs up to the previous step (or\n * cancels at step 0).\n *\n * Per research-2 §9.4: per-step validation inline, step counter `n/N`\n * only when N ≥ 2, Tab/Enter both advance, Esc backs up.\n *\n * This is deliberately minimal — a host that wants richer field\n * widgets can pass a custom `pickerRenderer`.\n */\n\n/// <reference lib=\"dom\" />\n\nimport { Command } from 'cmdk';\nimport { useState } from 'react';\nimport type { AnyCommandRecord } from 'acture';\nimport { readEnumOptions, summarizeParams, unwrap } from './derive-kind.js';\nimport type { ParamSummary } from './derive-kind.js';\n\nexport interface PickerChainProps {\n command: AnyCommandRecord;\n /** Initial values (e.g. defaults derived from context). */\n defaults?: Record<string, unknown>;\n /** Called when the user finishes the last step. */\n onSubmit: (params: Record<string, unknown>) => void;\n /** Called when the user cancels (Esc at step 0). */\n onCancel: () => void;\n}\n\nexport function PickerChain(props: PickerChainProps): React.ReactElement {\n const { command, defaults, onSubmit, onCancel } = props;\n const summary = summarizeParams(command);\n const [values, setValues] = useState<Record<string, unknown>>(() => ({ ...(defaults ?? {}) }));\n const [step, setStep] = useState(0);\n\n const current: ParamSummary | undefined = summary[step];\n\n function commit(value: unknown): void {\n if (!current) return;\n const next = { ...values, [current.name]: value };\n setValues(next);\n if (step + 1 >= summary.length) {\n onSubmit(next);\n } else {\n setStep(step + 1);\n }\n }\n\n function back(): void {\n if (step === 0) {\n onCancel();\n return;\n }\n setStep(step - 1);\n }\n\n if (!current) {\n // Should not normally render — fallback to submit.\n onSubmit(values);\n return <></>;\n }\n\n const counter = summary.length >= 2 ? `${step + 1}/${summary.length}` : null;\n const label = paramLabel(current);\n\n return (\n <div data-acture-picker-chain style={{ display: 'flex', flexDirection: 'column' }}>\n <div\n data-acture-picker-chain-header\n style={{ padding: '8px 12px', borderBottom: '1px solid var(--acture-divider, #eee)' }}\n >\n <strong>{command.title}</strong>\n {counter ? <span style={{ marginLeft: 8, opacity: 0.6 }}>{counter}</span> : null}\n <span style={{ marginLeft: 8, opacity: 0.6 }}>· {label}</span>\n </div>\n <Step key={`${command.id}.${current.name}`} param={current} initial={values[current.name]} onCommit={commit} onBack={back} />\n <div style={{ padding: '4px 12px', opacity: 0.6, fontSize: '0.85em' }}>\n ⏎ to advance · Esc to {step === 0 ? 'cancel' : 'go back'}\n </div>\n </div>\n );\n}\n\nfunction paramLabel(p: ParamSummary): string {\n const def = (p.schema as unknown as { description?: string }).description;\n if (typeof def === 'string' && def.length > 0) return def;\n return p.name;\n}\n\n/* ─────────────────────────── per-step UIs ─────────────────────────── */\n\ninterface StepProps {\n param: ParamSummary;\n initial: unknown;\n onCommit: (value: unknown) => void;\n onBack: () => void;\n}\n\nfunction Step(props: StepProps): React.ReactElement {\n const { param } = props;\n if (param.isPicker) {\n const enumOptions = readEnumOptions(param.schema);\n if (enumOptions.length > 0) {\n return <EnumPicker {...props} options={enumOptions} />;\n }\n // Boolean picker (or boolean-like via unwrap chain).\n const innerName = (unwrap(param.schema) as unknown as { _def?: { typeName?: string }; def?: { type?: string } });\n const t = innerName._def?.typeName ?? innerName.def?.type;\n if (t === 'ZodBoolean' || t === 'boolean') {\n return <EnumPicker {...props} options={['true', 'false']} coerce={(s) => s === 'true'} />;\n }\n }\n return <TextStep {...props} />;\n}\n\nfunction EnumPicker({\n param,\n initial,\n onCommit,\n onBack,\n options,\n coerce,\n}: StepProps & { options: readonly string[]; coerce?: (s: string) => unknown }): React.ReactElement {\n return (\n <Command label={`Pick ${param.name}`} shouldFilter={true}>\n <Command.Input\n placeholder={`Pick ${param.name}…`}\n autoFocus\n defaultValue={typeof initial === 'string' ? initial : ''}\n onKeyDown={(e) => {\n if (e.key === 'Escape') {\n e.preventDefault();\n onBack();\n }\n }}\n />\n <Command.List>\n <Command.Empty>No match.</Command.Empty>\n {options.map((opt) => (\n <Command.Item\n key={opt}\n value={opt}\n onSelect={() => onCommit(coerce ? coerce(opt) : opt)}\n >\n {opt}\n </Command.Item>\n ))}\n </Command.List>\n </Command>\n );\n}\n\nfunction TextStep({ param, initial, onCommit, onBack }: StepProps): React.ReactElement {\n const [draft, setDraft] = useState<string>(\n typeof initial === 'string' ? initial : initial === undefined ? '' : String(initial),\n );\n const [errorMsg, setErrorMsg] = useState<string | null>(null);\n\n function submit(): void {\n const coerced = coerceFromText(draft, param);\n const parseResult = (param.schema as unknown as { safeParse: (v: unknown) => { success: boolean; data?: unknown; error?: { issues?: { message: string }[] } } })\n .safeParse(coerced);\n if (!parseResult.success) {\n setErrorMsg(parseResult.error?.issues?.[0]?.message ?? 'Invalid value');\n return;\n }\n onCommit(parseResult.data);\n }\n\n return (\n <div style={{ padding: 8, display: 'flex', flexDirection: 'column', gap: 4 }}>\n <input\n data-acture-text-step\n autoFocus\n value={draft}\n placeholder={inferPlaceholder(param)}\n onChange={(e) => {\n setDraft(e.target.value);\n if (errorMsg) setErrorMsg(null);\n }}\n onKeyDown={(e) => {\n if (e.key === 'Enter') {\n e.preventDefault();\n submit();\n return;\n }\n if (e.key === 'Escape') {\n e.preventDefault();\n onBack();\n }\n }}\n style={{\n padding: '8px 10px',\n border: errorMsg ? '1px solid #c33' : '1px solid var(--acture-divider, #ccc)',\n borderRadius: 4,\n font: 'inherit',\n }}\n />\n {errorMsg ? (\n <span style={{ color: '#c33', fontSize: '0.85em' }} data-acture-validation-error>\n {errorMsg}\n </span>\n ) : null}\n </div>\n );\n}\n\nfunction coerceFromText(raw: string, p: ParamSummary): unknown {\n const inner = unwrap(p.schema) as unknown as { _def?: { typeName?: string }; def?: { type?: string } };\n const t = inner._def?.typeName ?? inner.def?.type;\n if (t === 'ZodNumber' || t === 'number') {\n const n = Number(raw);\n return Number.isFinite(n) ? n : raw;\n }\n if (t === 'ZodBoolean' || t === 'boolean') {\n return raw === 'true';\n }\n return raw;\n}\n\nfunction inferPlaceholder(p: ParamSummary): string {\n const inner = unwrap(p.schema) as unknown as { _def?: { typeName?: string }; def?: { type?: string } };\n const t = inner._def?.typeName ?? inner.def?.type;\n if (t === 'ZodNumber' || t === 'number') return `${p.name} (number)…`;\n if (t === 'ZodString' || t === 'string') return `${p.name}…`;\n return `${p.name}…`;\n}\n","/**\n * `<CommandPalette />` — Phase 2 implementation.\n *\n * Adds parameterized-command support per research-2 §9 (and the\n * `acture-palette-design` skill):\n *\n * - `deriveKind(command)` returns 'atomic' | 'handoff'. Authors may\n * override via `record.kind`.\n * - 'atomic' commands render an inline picker chain INSIDE the\n * palette (Linear / Discord chip-style).\n * - 'handoff' commands either render a host-supplied form inline\n * (when `formAdapter` is provided) or fall back to firing\n * `onParameterizedSelect` for the host to open its own form view.\n *\n * Phase 1 behavior is preserved for parameter-free commands and for\n * hosts that supply neither a form adapter nor a parameterized-select\n * callback — the palette just closes the picker view.\n *\n * Per `acture-hard-donts` skill: no bundled UI kit. All elements use\n * cmdk's built-in classes plus consumer-supplied className overrides.\n */\n\n/// <reference lib=\"dom\" />\n\nimport { Command } from 'cmdk';\nimport { useMemo, useState } from 'react';\nimport type {\n AnyCommandRecord,\n Context,\n Registry,\n Result,\n Tier,\n} from 'acture';\nimport { useCommandsChanged } from './use-commands-changed.js';\nimport { deriveKind } from './derive-kind.js';\nimport { PickerChain } from './picker-chain.js';\n\nexport type PaletteItemRenderer = (cmd: AnyCommandRecord) => React.ReactNode;\n\n/** Props the palette passes to a host-supplied form adapter. The host\n * renders a form derived from `command.params` and calls `onSubmit`\n * with the validated params (or `onCancel`). */\nexport interface PaletteFormAdapterProps {\n command: AnyCommandRecord;\n defaults?: Record<string, unknown>;\n onSubmit: (params: unknown) => void;\n onCancel: () => void;\n}\n\nexport type PaletteFormAdapter = React.ComponentType<PaletteFormAdapterProps>;\n\nexport interface CommandPaletteProps {\n /** The acture registry. */\n registry: Registry;\n /** Optional context for when-clause filtering and dispatch. */\n context?: Context;\n /** Tier filter. Default: `['stable']`. */\n tiers?: readonly Tier[] | 'all';\n /** Called when a dispatch (parameter-free OR parameterized) finishes. */\n onDispatched?: (cmd: AnyCommandRecord, result: Result<unknown>) => void;\n /** Fired when the user picks a `handoff` command and no `formAdapter`\n * is configured. Hosts that want to open their own form view should\n * handle this. */\n onParameterizedSelect?: (cmd: AnyCommandRecord) => void;\n /** Optional form adapter for `handoff` commands. When present, the\n * palette switches its inner view to this component instead of\n * closing. Plug in `acture-forms-autoform` or `acture-forms-rjsf`. */\n formAdapter?: PaletteFormAdapter;\n /** Per-field defaults injected into the picker chain / form. Useful\n * for context-aware prefill (Things-style — research-2 §9.4). */\n paramDefaults?: (cmd: AnyCommandRecord) => Record<string, unknown> | undefined;\n placeholder?: string;\n className?: string;\n /** Custom item renderer for the list view. */\n renderItem?: PaletteItemRenderer;\n}\n\ntype View =\n | { kind: 'list' }\n | { kind: 'pickerChain'; cmd: AnyCommandRecord; defaults?: Record<string, unknown> }\n | { kind: 'form'; cmd: AnyCommandRecord; defaults?: Record<string, unknown> };\n\nexport function CommandPalette(props: CommandPaletteProps): React.ReactElement {\n const {\n registry,\n context,\n tiers,\n onDispatched,\n onParameterizedSelect,\n formAdapter,\n paramDefaults,\n placeholder = 'Type a command…',\n className,\n renderItem,\n } = props;\n\n const revision = useCommandsChanged(registry);\n const [view, setView] = useState<View>({ kind: 'list' });\n\n const groups = useMemo(() => {\n const list = registry.list({\n tiers: tiers ?? ['stable'],\n ...(context !== undefined ? { context } : {}),\n });\n return groupByCategory(list);\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [registry, revision, tiers, context]);\n\n async function dispatchCommand(cmd: AnyCommandRecord, params?: unknown): Promise<void> {\n const result = await registry.dispatch(cmd.id, params, context);\n onDispatched?.(cmd, result);\n setView({ kind: 'list' });\n }\n\n function selectFromList(id: string): void {\n const cmd = registry.get(id);\n if (!cmd) return;\n if (cmd.params === undefined) {\n void dispatchCommand(cmd);\n return;\n }\n const defaults = paramDefaults?.(cmd);\n const kind = deriveKind(cmd);\n if (kind === 'atomic') {\n const next: View = defaults !== undefined\n ? { kind: 'pickerChain', cmd, defaults }\n : { kind: 'pickerChain', cmd };\n setView(next);\n return;\n }\n // handoff\n if (formAdapter) {\n const next: View = defaults !== undefined\n ? { kind: 'form', cmd, defaults }\n : { kind: 'form', cmd };\n setView(next);\n return;\n }\n onParameterizedSelect?.(cmd);\n }\n\n if (view.kind === 'pickerChain') {\n const chainProps: Parameters<typeof PickerChain>[0] = view.defaults !== undefined\n ? {\n command: view.cmd,\n defaults: view.defaults,\n onSubmit: (params) => { void dispatchCommand(view.cmd, params); },\n onCancel: () => setView({ kind: 'list' }),\n }\n : {\n command: view.cmd,\n onSubmit: (params) => { void dispatchCommand(view.cmd, params); },\n onCancel: () => setView({ kind: 'list' }),\n };\n return (\n <div className={className} data-acture-palette-view=\"picker-chain\">\n <PickerChain {...chainProps} />\n </div>\n );\n }\n\n if (view.kind === 'form' && formAdapter) {\n const FormAdapter = formAdapter;\n const formProps: PaletteFormAdapterProps = view.defaults !== undefined\n ? {\n command: view.cmd,\n defaults: view.defaults,\n onSubmit: (params) => { void dispatchCommand(view.cmd, params); },\n onCancel: () => setView({ kind: 'list' }),\n }\n : {\n command: view.cmd,\n onSubmit: (params) => { void dispatchCommand(view.cmd, params); },\n onCancel: () => setView({ kind: 'list' }),\n };\n return (\n <div className={className} data-acture-palette-view=\"form\">\n <FormAdapter {...formProps} />\n </div>\n );\n }\n\n return (\n <Command className={className} label=\"Command palette\" data-acture-palette-view=\"list\">\n <Command.Input placeholder={placeholder} autoFocus />\n <Command.List>\n <Command.Empty>No matching commands.</Command.Empty>\n {groups.map(([category, items]) => (\n <Command.Group key={category} heading={category}>\n {items.map((cmd) => (\n <Command.Item\n key={cmd.id}\n value={paletteValue(cmd)}\n keywords={cmd.aliases ? [...cmd.aliases] : undefined}\n onSelect={() => selectFromList(cmd.id)}\n >\n {renderItem ? renderItem(cmd) : <DefaultItem cmd={cmd} />}\n </Command.Item>\n ))}\n </Command.Group>\n ))}\n </Command.List>\n </Command>\n );\n}\n\n/* ───────────────────────── default rendering ──────────────────────── */\n\nfunction DefaultItem({ cmd }: { cmd: AnyCommandRecord }): React.ReactElement {\n const isParameterized = cmd.params !== undefined;\n const kind = isParameterized ? deriveKind(cmd) : null;\n const keybinding = formatKeybinding(cmd.keybinding);\n return (\n <span\n data-acture-palette-item\n data-acture-parameterized={isParameterized ? '' : undefined}\n data-acture-kind={kind ?? undefined}\n style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', gap: 8, flex: 1 }}\n >\n <span style={{ display: 'flex', alignItems: 'center', gap: 6 }}>\n {cmd.icon ? <span aria-hidden=\"true\">{cmd.icon}</span> : null}\n <span>{cmd.title}</span>\n {isParameterized ? (\n <span\n data-acture-kind-badge\n style={{\n fontSize: '0.7em',\n opacity: 0.6,\n padding: '0 4px',\n border: '1px solid currentColor',\n borderRadius: 4,\n }}\n >\n {kind === 'atomic' ? '⇥' : '…'}\n </span>\n ) : null}\n </span>\n {keybinding ? (\n <kbd style={{ fontSize: '0.85em', opacity: 0.7 }}>{keybinding}</kbd>\n ) : null}\n </span>\n );\n}\n\n/* ─────────────────────────── helpers ──────────────────────────────── */\n\nfunction paletteValue(cmd: AnyCommandRecord): string {\n const parts = [cmd.title, cmd.id];\n if (cmd.aliases) parts.push(...cmd.aliases);\n if (cmd.category) parts.push(cmd.category);\n return parts.join(' ');\n}\n\nfunction formatKeybinding(kb: AnyCommandRecord['keybinding']): string | null {\n if (kb === undefined) return null;\n if (typeof kb === 'string') return kb;\n if (kb.length === 0) return null;\n return kb[0] ?? null;\n}\n\nfunction groupByCategory(\n list: readonly AnyCommandRecord[],\n): readonly (readonly [string, readonly AnyCommandRecord[]])[] {\n const groups = new Map<string, AnyCommandRecord[]>();\n const ordered: string[] = [];\n for (const cmd of list) {\n const category = cmd.category ?? 'Commands';\n if (!groups.has(category)) {\n groups.set(category, []);\n ordered.push(category);\n }\n groups.get(category)!.push(cmd);\n }\n for (const items of groups.values()) {\n items.sort((a, b) => {\n const sa = scoreOf(a);\n const sb = scoreOf(b);\n if (sa !== sb) return sb - sa;\n return a.title.localeCompare(b.title);\n });\n }\n return ordered.map((cat) => [cat, groups.get(cat) as readonly AnyCommandRecord[]] as const);\n}\n\nfunction scoreOf(cmd: AnyCommandRecord): number {\n if (typeof cmd.defaultScore === 'number') return cmd.defaultScore;\n return 0;\n}\n"]}
package/package.json ADDED
@@ -0,0 +1,66 @@
1
+ {
2
+ "name": "acture-palette-react",
3
+ "version": "1.0.0",
4
+ "description": "acture command palette for React — minimal Phase 1 version. Parameter-free commands only.",
5
+ "license": "Apache-2.0",
6
+ "author": "Thor Whalen",
7
+ "repository": {
8
+ "type": "git",
9
+ "url": "git+https://github.com/thorwhalen/acture.git",
10
+ "directory": "packages/palette-react"
11
+ },
12
+ "homepage": "https://github.com/thorwhalen/acture#readme",
13
+ "bugs": "https://github.com/thorwhalen/acture/issues",
14
+ "type": "module",
15
+ "files": [
16
+ "dist",
17
+ "README.md",
18
+ "LICENSE"
19
+ ],
20
+ "main": "./dist/index.cjs",
21
+ "module": "./dist/index.js",
22
+ "types": "./dist/index.d.ts",
23
+ "exports": {
24
+ ".": {
25
+ "types": "./dist/index.d.ts",
26
+ "import": "./dist/index.js",
27
+ "require": "./dist/index.cjs"
28
+ },
29
+ "./package.json": "./package.json"
30
+ },
31
+ "sideEffects": false,
32
+ "peerDependencies": {
33
+ "cmdk": "^1.0.0",
34
+ "react": "^18.0.0 || ^19.0.0",
35
+ "acture": "1.1.0"
36
+ },
37
+ "devDependencies": {
38
+ "@testing-library/react": "^16.1.0",
39
+ "@types/react": "^19.0.0",
40
+ "@vitejs/plugin-react": "^4.3.4",
41
+ "cmdk": "^1.0.0",
42
+ "jsdom": "^25.0.0",
43
+ "react": "^19.0.0",
44
+ "react-dom": "^19.0.0",
45
+ "tsup": "^8.3.0",
46
+ "typescript": "^5.7.0",
47
+ "vitest": "^2.1.0",
48
+ "zod": "^4.0.0",
49
+ "acture": "1.1.0"
50
+ },
51
+ "keywords": [
52
+ "acture",
53
+ "command-palette",
54
+ "cmdk",
55
+ "react"
56
+ ],
57
+ "publishConfig": {
58
+ "access": "public"
59
+ },
60
+ "scripts": {
61
+ "build": "tsup",
62
+ "typecheck": "tsc --noEmit",
63
+ "test": "vitest run",
64
+ "clean": "rm -rf dist *.tsbuildinfo"
65
+ }
66
+ }