stillmade-sdk 0.1.34 → 0.1.35

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "stillmade-sdk",
3
- "version": "0.1.34",
3
+ "version": "0.1.35",
4
4
  "description": "StillMade Block SDK, CLI and examples",
5
5
  "license": "PolyForm-Shield-1.0.0",
6
6
  "type": "module",
@@ -15,13 +15,21 @@ export function createSchemaFields(lockedInputKeys=[]) {
15
15
  function read(root,path){pathCheck(path);inert(root);let item=root;for(const key of path){if(!item||typeof item!=='object'||!Object.hasOwn(item,key))return undefined;item=item[key];}return item===undefined?undefined:copy(item);}
16
16
  function set(root,path,value){pathCheck(path);const result=copy(root);inert(value);let item=result;for(let i=0;i<path.length-1;i++){const key=path[i];if(!Object.hasOwn(item,key)||item[key]===null||typeof item[key]!=='object')item[key]=typeof path[i+1]==='number'?[]:{};item=item[key];}item[path.at(-1)]=copy(value);return result;}
17
17
  function empty(s){if(Object.hasOwn(s,'default'))return copy(s.default);if(Array.isArray(s.enum)&&s.enum.length)return copy(s.enum[0]);return s.type==='object'?{}:s.type==='array'?[]:s.type==='boolean'?false:['integer','number'].includes(s.type)?Math.max(s.minimum||0,0):'';}
18
+ function hint(description){
19
+ const text=typeof description==='string'?description.replace(/\s+/g,' ').trim():'';if(!text)return '';
20
+ const [first,second]=text.split(/(?<=[.!?])\s+(?=[A-Z])/);
21
+ const kept=second&&first.length+second.length<280?first+' '+second:first;
22
+ return kept.length>280?kept.slice(0,279).trimEnd()+'…':kept;
23
+ }
18
24
  function controls(schema,bindings,values,{canEdit=true,busy=false}={}) {
19
25
  inert(schema);inert(bindings);inert(values);let count=0;const tree=[],actions=[];
20
26
  const action=(kind,path,s)=>{const id=`field-${actions.length}`;actions.push({id,kind,path,s});return id;};
21
27
  function fields(s,path,value,label,required,depth) {
22
28
  if(++count>150||depth>5)return [{tag:'p',text:'This task needs a custom interface for its remaining fields.'}];
23
- const result=[{tag:'label',text:String(label).slice(0,240)+(required?' *':' (optional)')}],disabled=busy||!canEdit||locked.has(path[0]);
24
- if(s.description)result.push({tag:'small',text:String(s.description).slice(0,1000)});
29
+ // A description sits behind an (i) beside its label, one or two sentences:
30
+ // connected apps describe fields at length for AI models, not people.
31
+ const name=String(label).slice(0,240)+(required?' *':' (optional)'),about=hint(s.description);
32
+ const result=[about?{tag:'div',className:'sm-label',children:[{tag:'label',text:name},{tag:'details',className:'sm-hint',children:[{tag:'summary',label:'About '+String(label).slice(0,200)},{tag:'p',text:about}]}]}:{tag:'label',text:name}],disabled=busy||!canEdit||locked.has(path[0]);
25
33
  if(s.type==='object'&&s.properties){for(const key of Object.keys(s.properties))result.push({tag:'section',children:fields(s.properties[key],path.concat(key),value?.[key],s.properties[key].title||key,(s.required||[]).includes(key),depth+1)});}
26
34
  else if(s.type==='array'){
27
35
  const rows=Array.isArray(value)?value:[];