stillmade-sdk 0.1.28 → 0.1.29

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.28",
3
+ "version": "0.1.29",
4
4
  "description": "StillMade Block SDK, CLI and examples",
5
5
  "license": "PolyForm-Shield-1.0.0",
6
6
  "type": "module",
@@ -193,8 +193,11 @@ export async function readPackage(path) {
193
193
  if(localModule||viewFiles)moduleFiles.set(pkg,{...(localModule?.files||{}),...(viewFiles||{})});
194
194
  return pkg;
195
195
  }
196
+ export const MODULE_EXECUTION_REQUIRED_MESSAGE='This Block runs code, so the gate a hook starts does not run it. Run `stillmade-block gate .` (`npx stillmade-block gate .` in an npm project) yourself and report the status it prints.';
196
197
  export async function main(rawArgs) {
197
- const mockRequested=rawArgs.includes('--mock'),args=rawArgs.filter(value=>value!=='--mock');
198
+ // --no-module-execution: what the gate a hook starts passes to ready, so a module Block is refused
199
+ // before anything of it runs; the decision is made on the same parsed package ready would run.
200
+ const mockRequested=rawArgs.includes('--mock'),noModuleExecution=rawArgs.includes('--no-module-execution'),args=rawArgs.filter(value=>value!=='--mock'&&value!=='--no-module-execution');
198
201
  if(!args.length||['help','--help','-h'].includes(args[0])||args.includes('--help')||args.includes('-h'))return {help:HELP};
199
202
  if(args[0]==='templates'||args[0]==='create'&&args.includes('--list'))return {templates:Object.entries(TEMPLATES).map(([name,template])=>({name,runtime:template.runtime,description:template.description}))};
200
203
  const [command, target = '.', extra] = args, path = resolve(target);
@@ -251,7 +254,9 @@ export async function main(rawArgs) {
251
254
  // On the creator's own machine a module Block runs in the SDK's Node executor with the
252
255
  // stand-in host that answers from tests/mocks.json, as test and preview do (October 20,
253
256
  // 2026: ready refused every module Block at DOD-01, so none could pass the gate from the SDK).
254
- const mock=pkg.manifest?.runtime==='module'?await standIns(path,pkg,true):null;
257
+ const module=pkg.manifest?.runtime==='module';
258
+ if(module&&noModuleExecution)throw Object.assign(new Error(MODULE_EXECUTION_REQUIRED_MESSAGE),{code:'MODULE_EXECUTION_REQUIRED'});
259
+ const mock=module?await standIns(path,pkg,true):null;
255
260
  const readiness=await assessBlockReadiness(pkg,{moduleExecution:true,files:moduleFiles.get(pkg),...(mock?{host:mock.host}:{})});
256
261
  if(['FAILED','BLOCKED BY PLATFORM CAPABILITY'].includes(readiness.status))throw Object.assign(new Error(`Block readiness: ${readiness.status}`),{report:readiness});
257
262
  return readiness;
@@ -88,10 +88,11 @@ const summarize=readiness=>(readiness?.items||[]).filter(item=>['failed','blocke
88
88
  export const RUN_READY_YOURSELF='RUN READY YOURSELF';
89
89
  async function judge(path,main,{executeModules=true}={}){
90
90
  try{
91
+ // ready decides on the package it would run: with --no-module-execution it refuses a module
92
+ // Block before anything of it runs (MODULE_EXECUTION_REQUIRED), so the gate never falls open.
93
+ const readiness=await main(['ready',path,...(executeModules?[]:['--no-module-execution'])]);
91
94
  // Every new or edited Block carries its feature map (builder-contract); search, matching and its listing read it.
92
95
  const manifest=(await main(['inspect',path]).catch(()=>null))?.manifest;
93
- if(!executeModules&&manifest?.runtime==='module')return {ok:false,status:RUN_READY_YOURSELF,failures:['This Block runs code, so the gate a hook starts does not run it. Run `stillmade-block gate .` (`npx stillmade-block gate .` in an npm project) yourself and report the status it prints.'],limitations:0};
94
- const readiness=await main(['ready',path]);
95
96
  // The starting map create writes (one entry copied from the description) does not count until it is rewritten.
96
97
  const placeholder=features=>features.length===1&&features[0].id==='main'&&features[0].asks?.length===1&&features[0].asks[0]===features[0].does;
97
98
  if(PASSING.has(readiness.status)&&manifest&&!(Array.isArray(manifest.features)&&manifest.features.length&&!placeholder(manifest.features)))
@@ -102,6 +103,7 @@ async function judge(path,main,{executeModules=true}={}){
102
103
  try{await main(['test',path]);return {ok:true,status:'PROJECT TYPE TESTS PASSED',failures:[]};}
103
104
  catch(typeError){return {ok:false,status:'FAILED',failures:[String(typeError.message).slice(0,300)]};}
104
105
  }
106
+ if(error.code==='MODULE_EXECUTION_REQUIRED')return {ok:false,status:RUN_READY_YOURSELF,failures:[String(error.message).slice(0,400)],limitations:0};
105
107
  if(error.code==='APPLICATION_REVIEW_REQUIRED')return {ok:false,status:'NEEDS STILLMADE REVIEW',failures:[String(error.message).slice(0,400)]};
106
108
  if(error.report?.status)return {ok:false,status:error.report.status,failures:summarize(error.report)};
107
109
  return {ok:false,status:'FAILED',failures:[String(error.message).slice(0,300)]};