@coffer-org/sdk 2.1.3 → 2.2.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.
@@ -152,6 +152,22 @@ export declare function snippet(o: CodeOpts & {
152
152
  key?: undefined;
153
153
  value?: undefined;
154
154
  }): FieldMeta;
155
+ export declare const SOURCE_DEFAULT_MAX_BYTES = 262144;
156
+ export declare function isBinaryText(v: string): boolean;
157
+ export interface SourceOpts extends FieldCoreOpts {
158
+ label?: string;
159
+ }
160
+ export declare function source(o: SourceOpts & {
161
+ key: string;
162
+ }): FieldItem;
163
+ export declare function source(o: SourceOpts & {
164
+ value: unknown;
165
+ key?: undefined;
166
+ }): StaticEl;
167
+ export declare function source(o: SourceOpts & {
168
+ key?: undefined;
169
+ value?: undefined;
170
+ }): FieldMeta;
155
171
  export interface RatingOpts extends FieldCoreOpts {
156
172
  label?: string;
157
173
  }
@@ -242,6 +258,7 @@ export declare const presets: {
242
258
  tags: typeof tags;
243
259
  markdown: typeof markdown;
244
260
  snippet: typeof snippet;
261
+ source: typeof source;
245
262
  rating: typeof rating;
246
263
  duration: typeof duration;
247
264
  reminder: typeof reminder;
@@ -1,5 +1,5 @@
1
1
  import { z } from 'zod';
2
- import { real, int, text, date, select, string, group, vmsg, jsonRefined, typeErr, optionalize, applyMultiple, wrapKey, normalizeOpts, } from "./fields.js";
2
+ import { real, int, text, date, select, string, group, vmsg, jsonRefined, typeErr, reqTypeErr, optionalize, applyMultiple, wrapKey, normalizeOpts, } from "./fields.js";
3
3
  export function email(raw) {
4
4
  const o = normalizeOpts(raw);
5
5
  const required = o.required ?? false;
@@ -225,6 +225,34 @@ export function snippet(raw) {
225
225
  };
226
226
  return wrapKey(norm, meta);
227
227
  }
228
+ export const SOURCE_DEFAULT_MAX_BYTES = 262_144;
229
+ export function isBinaryText(v) {
230
+ return v.includes('\x00') || v.includes('�');
231
+ }
232
+ export function source(raw) {
233
+ const o = normalizeOpts(raw);
234
+ const required = o.required ?? false;
235
+ const ext = o.ext ?? 'txt';
236
+ const maxBytes = o.maxBytes ?? SOURCE_DEFAULT_MAX_BYTES;
237
+ const s = z.string(reqTypeErr()).superRefine((v, ctx) => {
238
+ if (isBinaryText(v)) {
239
+ ctx.addIssue({ code: z.ZodIssueCode.custom, message: vmsg('source_binary') });
240
+ return;
241
+ }
242
+ if (new TextEncoder().encode(v).length > maxBytes)
243
+ ctx.addIssue({ code: z.ZodIssueCode.custom, message: vmsg('source_too_large', { maxBytes }) });
244
+ });
245
+ const meta = {
246
+ kind: 'source',
247
+ label: o.label ?? '',
248
+ required,
249
+ prim: 'text',
250
+ column: 'text',
251
+ hints: { ext, maxBytes, noEditControl: true },
252
+ zod: optionalize(s, required),
253
+ };
254
+ return wrapKey(o, meta);
255
+ }
228
256
  export function rating(raw) {
229
257
  const o = normalizeOpts(raw);
230
258
  const required = o.required ?? false;
@@ -328,6 +356,7 @@ export const presets = {
328
356
  tags,
329
357
  markdown,
330
358
  snippet,
359
+ source,
331
360
  rating,
332
361
  duration,
333
362
  reminder,
@@ -13,6 +13,8 @@ export interface Rules {
13
13
  unique?: string[];
14
14
  fixed?: boolean;
15
15
  exts?: string[];
16
+ ext?: string;
17
+ maxBytes?: number;
16
18
  lead?: number;
17
19
  by?: FieldItem;
18
20
  }
@@ -66,6 +68,8 @@ export type NormalizedOpts = {
66
68
  unique?: string[];
67
69
  fixed?: boolean;
68
70
  exts?: string[];
71
+ ext?: string;
72
+ maxBytes?: number;
69
73
  lead?: number;
70
74
  by?: FieldItem;
71
75
  min?: number | string;
@@ -28,6 +28,8 @@ export function normalizeOpts(rawIn) {
28
28
  unique: r.unique,
29
29
  fixed: r.fixed,
30
30
  exts: r.exts,
31
+ ext: r.ext,
32
+ maxBytes: r.maxBytes,
31
33
  lead: r.lead,
32
34
  by: r.by,
33
35
  min: r.min,
package/dist/shelf.d.ts CHANGED
@@ -24,6 +24,7 @@ export interface ShelfDef {
24
24
  icon?: string;
25
25
  claude?: string;
26
26
  standalone?: boolean;
27
+ single?: boolean;
27
28
  views?: ShelfViews;
28
29
  fields: LayoutEl[];
29
30
  }
package/dist/shelf.js CHANGED
@@ -68,7 +68,9 @@ export function defineShelf(m) {
68
68
  const dup = keys.find((k, i) => keys.indexOf(k) !== i);
69
69
  if (dup)
70
70
  throw new Error(`[shelf] ${m.library}/${m.shelf}: duplicate key '${dup}'`);
71
- if (m.standalone !== false && !m.views?.list?.fields?.length)
71
+ if (m.single && !m.claude)
72
+ throw new Error(`[shelf] ${m.library}/${m.shelf}: single shelf requires \`claude\` — the agent cannot find it otherwise`);
73
+ if (m.standalone !== false && !m.single && !m.views?.list?.fields?.length)
72
74
  console.warn(`[shelf] ${m.library}/${m.shelf}: standalone shelf without an explicit views.list`);
73
75
  return m;
74
76
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@coffer-org/sdk",
3
- "version": "2.1.3",
3
+ "version": "2.2.0",
4
4
  "type": "module",
5
5
  "engines": {
6
6
  "node": ">=24"