stillmade-sdk 0.1.1 → 0.1.3

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/AGENTS.md CHANGED
@@ -8,6 +8,10 @@ Contract `stillmade.block-builder@1.0.0`. Humans, coding agents, imported source
8
8
 
9
9
  Treat the current SDK (`stillmade.block.json` manifest, `packages/block-sdk` contracts, validators, examples and published docs) as the source of truth. Before writing code, read the manifest contract, at least two working first-party Blocks closest to the request, the runtime you will use, the typed port and resolver contracts, and the shared-interface contract when you need a custom view. Do not invent runtimes, operations, permissions, ports, host services or bridge calls. If the documentation and the validator disagree, the validator wins and the mismatch should be reported.
10
10
 
11
+ ## Reuse first
12
+
13
+ Before building, check what already exists (`find_existing_blocks` over MCP, or the Marketplace and your library) by the inputs, results and operations the goal needs. Use an installed or reviewed Block that already does it; remix a close one so its license, notices and creator credit stay attached; chain existing Blocks and build only the missing step. Never republish another creator's source without remix lineage: public copies are refused. Build a new Block when nothing fits or the person asks for their own version, and say which similar Blocks you considered.
14
+
11
15
  ## Define the capability first
12
16
 
13
17
  Translate the request into an explicit capability contract before implementation: what the Block does; each input with its type, meaning and whether it is required (prefer optional settings with safe defaults over extra required questions); each output with its type and meaning; persistent state; project context it reads; permissions; UI; long-running behavior; expected failures; cancellation; determinism; and whether it needs hosted models, media, desktop tools or shared editing. Keep the public interface as small and general as possible and keep implementation details out of it.
package/NATIVE_MCP.md CHANGED
@@ -105,10 +105,10 @@ Use the backend origin, without a path. HTTP is accepted only for localhost. Red
105
105
 
106
106
  ## Available user actions
107
107
 
108
- - `list_catalog`, `search_marketplace`
108
+ - `list_catalog`, `search_marketplace`, `find_existing_blocks`
109
109
  - `search_github_candidates`, `inspect_github_repository`, `read_github_source`, `inspect_github_sdk_package`
110
110
  - `get_block_authoring_guide`, `search_documentation`, `validate_block_source`, `test_block_source`
111
- - `list_creations`, `get_creation`, `save_creation`
111
+ - `list_creations`, `get_creation`, `save_creation`, `begin_block_remix`
112
112
  - `list_projects`, `get_project_context`
113
113
  - `get_run`, `list_recent_runs`
114
114
  - With `analytics:read`: `get_creator_analytics`, `get_creator_retention`, `get_creator_dotplot`, `get_my_listing_reviews`
@@ -119,11 +119,30 @@ Live-tab inspection and control are no longer exposed in the app connection UI.
119
119
  External MCP clients continue to use the saved catalog, creation, project-context,
120
120
  and run-inspection tools listed above.
121
121
 
122
+ ## Reuse first
123
+
124
+ Before authoring, the client calls `find_existing_blocks` with the goal and, when
125
+ known, the inputs it starts from and the results it must produce. It searches
126
+ reviewed Marketplace listings, tested Community Blocks, built-ins and the
127
+ person's own Blocks by function and name, with no model, provider or credit
128
+ cost, and returns one outcome:
129
+
130
+ - `use` or `use-own`: an existing Block already does it; offer it instead of building.
131
+ - `remix`: a close Block allows an attributed remix. `begin_block_remix` creates a
132
+ private draft from that exact version, with its license, notices and creator
133
+ credit; retrying the same `requestId` returns the same draft.
134
+ - `compose` or `build-gap`: existing Blocks chain together; build only the missing step.
135
+ - `build`: nothing close exists, or the person wants their own version.
136
+
137
+ `validate_block_source` and `save_creation` also list up to three similar existing
138
+ Blocks (`similarExisting`). Publishing an exact copy of another creator's public
139
+ Block without remix lineage is refused.
140
+
122
141
  ## Block authoring uses the connected model
123
142
 
124
143
  When a user asks Claude, GPT, or another MCP client to create or refine a Block,
125
144
  the connected client model writes the complete SDK package itself. The default
126
- sequence is `get_block_authoring_guide`, targeted `search_documentation` calls,
145
+ sequence is `find_existing_blocks`, `get_block_authoring_guide`, targeted `search_documentation` calls,
127
146
  local source composition by that model, `validate_block_source`, repair of every
128
147
  reported failure, optional offline `test_block_source` for an eligible package,
129
148
  and `save_creation` with `kind: "block"` and the observed
package/PASTE_TO_LLM.md CHANGED
@@ -10,6 +10,10 @@ Contract `stillmade.block-builder@1.0.0`. Humans, coding agents, imported source
10
10
 
11
11
  Treat the current SDK (`stillmade.block.json` manifest, `packages/block-sdk` contracts, validators, examples and published docs) as the source of truth. Before writing code, read the manifest contract, at least two working first-party Blocks closest to the request, the runtime you will use, the typed port and resolver contracts, and the shared-interface contract when you need a custom view. Do not invent runtimes, operations, permissions, ports, host services or bridge calls. If the documentation and the validator disagree, the validator wins and the mismatch should be reported.
12
12
 
13
+ ### Reuse first
14
+
15
+ Before building, check what already exists (`find_existing_blocks` over MCP, or the Marketplace and your library) by the inputs, results and operations the goal needs. Use an installed or reviewed Block that already does it; remix a close one so its license, notices and creator credit stay attached; chain existing Blocks and build only the missing step. Never republish another creator's source without remix lineage: public copies are refused. Build a new Block when nothing fits or the person asks for their own version, and say which similar Blocks you considered.
16
+
13
17
  ### Define the capability first
14
18
 
15
19
  Translate the request into an explicit capability contract before implementation: what the Block does; each input with its type, meaning and whether it is required (prefer optional settings with safe defaults over extra required questions); each output with its type and meaning; persistent state; project context it reads; permissions; UI; long-running behavior; expected failures; cancellation; determinism; and whether it needs hosted models, media, desktop tools or shared editing. Keep the public interface as small and general as possible and keep implementation details out of it.
package/REMIX.md CHANGED
@@ -5,6 +5,20 @@ The original release, installed pins and saved projects remain intact. Remixes
5
5
  use the ordinary Block Builder, validator, package format and release pipeline.
6
6
  Project Types, projects and generated outputs are outside this workflow.
7
7
 
8
+ ## Find before you build
9
+
10
+ Check what already exists before writing a new Block. Create runs a free check
11
+ before every new build, and MCP clients call `find_existing_blocks`. Both search
12
+ reviewed Marketplace listings, tested Community Blocks, built-ins and your own
13
+ Blocks by what they take in, produce and call, and by name. The answer is one of:
14
+ use an existing Block, open your own, remix a close one, chain existing Blocks
15
+ and build only the missing step, or build new. Over MCP, `begin_block_remix`
16
+ starts a remix from an exact public version.
17
+
18
+ Publishing a renamed copy of another creator's public Block is refused; remix it
19
+ so its license, notices and creator credit stay attached. Max accounts can keep
20
+ such a copy private.
21
+
8
22
  ## Required for every finished Block
9
23
 
10
24
  Automatic remixing is a minimum admission requirement, including private Blocks.
package/SDK.md CHANGED
@@ -160,6 +160,10 @@ Contract `stillmade.block-builder@1.0.0`. Humans, coding agents, imported source
160
160
 
161
161
  Treat the current SDK (`stillmade.block.json` manifest, `packages/block-sdk` contracts, validators, examples and published docs) as the source of truth. Before writing code, read the manifest contract, at least two working first-party Blocks closest to the request, the runtime you will use, the typed port and resolver contracts, and the shared-interface contract when you need a custom view. Do not invent runtimes, operations, permissions, ports, host services or bridge calls. If the documentation and the validator disagree, the validator wins and the mismatch should be reported.
162
162
 
163
+ ### Reuse first
164
+
165
+ Before building, check what already exists (`find_existing_blocks` over MCP, or the Marketplace and your library) by the inputs, results and operations the goal needs. Use an installed or reviewed Block that already does it; remix a close one so its license, notices and creator credit stay attached; chain existing Blocks and build only the missing step. Never republish another creator's source without remix lineage: public copies are refused. Build a new Block when nothing fits or the person asks for their own version, and say which similar Blocks you considered.
166
+
163
167
  ### Define the capability first
164
168
 
165
169
  Translate the request into an explicit capability contract before implementation: what the Block does; each input with its type, meaning and whether it is required (prefer optional settings with safe defaults over extra required questions); each output with its type and meaning; persistent state; project context it reads; permissions; UI; long-running behavior; expected failures; cancellation; determinism; and whether it needs hosted models, media, desktop tools or shared editing. Keep the public interface as small and general as possible and keep implementation details out of it.
@@ -7052,6 +7056,10 @@ Contract `stillmade.block-builder@1.0.0`. Humans, coding agents, imported source
7052
7056
 
7053
7057
  Treat the current SDK (`stillmade.block.json` manifest, `packages/block-sdk` contracts, validators, examples and published docs) as the source of truth. Before writing code, read the manifest contract, at least two working first-party Blocks closest to the request, the runtime you will use, the typed port and resolver contracts, and the shared-interface contract when you need a custom view. Do not invent runtimes, operations, permissions, ports, host services or bridge calls. If the documentation and the validator disagree, the validator wins and the mismatch should be reported.
7054
7058
 
7059
+ ### Reuse first
7060
+
7061
+ Before building, check what already exists (`find_existing_blocks` over MCP, or the Marketplace and your library) by the inputs, results and operations the goal needs. Use an installed or reviewed Block that already does it; remix a close one so its license, notices and creator credit stay attached; chain existing Blocks and build only the missing step. Never republish another creator's source without remix lineage: public copies are refused. Build a new Block when nothing fits or the person asks for their own version, and say which similar Blocks you considered.
7062
+
7055
7063
  ### Define the capability first
7056
7064
 
7057
7065
  Translate the request into an explicit capability contract before implementation: what the Block does; each input with its type, meaning and whether it is required (prefer optional settings with safe defaults over extra required questions); each output with its type and meaning; persistent state; project context it reads; permissions; UI; long-running behavior; expected failures; cancellation; determinism; and whether it needs hosted models, media, desktop tools or shared editing. Keep the public interface as small and general as possible and keep implementation details out of it.
@@ -10350,6 +10358,20 @@ The original release, installed pins and saved projects remain intact. Remixes
10350
10358
  use the ordinary Block Builder, validator, package format and release pipeline.
10351
10359
  Project Types, projects and generated outputs are outside this workflow.
10352
10360
 
10361
+ ### Find before you build
10362
+
10363
+ Check what already exists before writing a new Block. Create runs a free check
10364
+ before every new build, and MCP clients call `find_existing_blocks`. Both search
10365
+ reviewed Marketplace listings, tested Community Blocks, built-ins and your own
10366
+ Blocks by what they take in, produce and call, and by name. The answer is one of:
10367
+ use an existing Block, open your own, remix a close one, chain existing Blocks
10368
+ and build only the missing step, or build new. Over MCP, `begin_block_remix`
10369
+ starts a remix from an exact public version.
10370
+
10371
+ Publishing a renamed copy of another creator's public Block is refused; remix it
10372
+ so its license, notices and creator credit stay attached. Max accounts can keep
10373
+ such a copy private.
10374
+
10353
10375
  ### Required for every finished Block
10354
10376
 
10355
10377
  Automatic remixing is a minimum admission requirement, including private Blocks.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "stillmade-sdk",
3
- "version": "0.1.1",
3
+ "version": "0.1.3",
4
4
  "description": "StillMade Block SDK, CLI and examples",
5
5
  "license": "PolyForm-Shield-1.0.0",
6
6
  "type": "module",
@@ -39,6 +39,12 @@ function bestRequirementMatch(manifest,requirement,semantics) {
39
39
  return matches.find(match=>match.exact) || matches[0] || null;
40
40
  }
41
41
 
42
+ /** The best result slot (an output, or a planned terminal action) that meets
43
+ * a required {type, semantic}: {compatible, exact, reason}, or null. */
44
+ export function requirementMatch(manifest,requirement,semantics) {
45
+ return bestRequirementMatch(manifest,requirement,semantics);
46
+ }
47
+
42
48
  export function blockProvidesRequirement(manifest,requirement,semantics) {
43
49
  return !!bestRequirementMatch(manifest,requirement,semantics);
44
50
  }
@@ -70,7 +76,7 @@ export function missingCapabilityPlacements(requirements,combination,candidates)
70
76
  });
71
77
  }
72
78
 
73
- export function recommendProjectTypeCombinations({goal,requirements,handoffRequirements=[],sourceMaterials, resultPins={},candidates,semantics,trustedUsage=[],trustedExecution=[],trustedCosts=[],trustedCreators=[],executionPreference='any',executionDevices=[],maxSteps=8,beamWidth=12,maxEvaluations=1200}) {
79
+ export function recommendProjectTypeCombinations({goal,requirements,handoffRequirements=[],sourceMaterials, resultPins={},candidates,semantics,trustedUsage=[],trustedExecution=[],trustedCosts=[],trustedCreators=[],trustedQuality=[],executionPreference='any',executionDevices=[],maxSteps=8,beamWidth=12,maxEvaluations=1200}) {
74
80
  assert(RECOMMENDATION_EXECUTION_PREFERENCES.includes(executionPreference),'RECOMMENDATION','Choose an available execution preference.');
75
81
  assert(Array.isArray(executionDevices)&&executionDevices.length<=3&&new Set(executionDevices).size===executionDevices.length&&executionDevices.every(device=>RECOMMENDATION_EXECUTION_DEVICES.includes(device)),'RECOMMENDATION','Choose only phone, browser, or desktop execution devices.');
76
82
  assert(typeof goal==='string' && goal.trim() && goal.length<=4000,'RECOMMENDATION','Describe what the software should do.');
@@ -103,6 +109,9 @@ export function recommendProjectTypeCombinations({goal,requirements,handoffRequi
103
109
  const available=[...catalog.values()];
104
110
  const usage=new Map(trustedUsage.filter(row=>Number.isSafeInteger(row.completedProjects) && row.completedProjects>=0 && Number.isSafeInteger(row.repeatUsers) && row.repeatUsers>=0).map(row=>[`${row.entityId}@${row.version}:${row.digest}`,row]));
105
111
  const usageFor=candidate=>candidate.release?usage.get(`${candidate.release.entityId}@${candidate.release.version}:${candidate.release.digest}`):undefined;
112
+ // Distinct people other than the creator who installed each Block. A tie-break only.
113
+ const installs=new Map(trustedQuality.filter(row=>typeof row?.entityId==='string'&&Number.isSafeInteger(row.installs)&&row.installs>=0).map(row=>[row.entityId,row.installs]));
114
+ const installsFor=candidate=>candidate.release?installs.get(candidate.release.entityId):undefined;
106
115
  const execution=new Map(trustedExecution.filter(row=>Number.isSafeInteger(row.terminalRuns) && row.terminalRuns>=5 && Number.isSafeInteger(row.completedRuns) && row.completedRuns>=0 && row.completedRuns<=row.terminalRuns && Number.isSafeInteger(row.observedUsers) && row.observedUsers>=3 && row.observedUsers<=row.terminalRuns).map(row=>[`${row.entityId}@${row.version}:${row.digest}`,row]));
107
116
  const executionFor=candidate=>candidate.release?execution.get(`${candidate.release.entityId}@${candidate.release.version}:${candidate.release.digest}`):undefined;
108
117
  const costs=new Map(trustedCosts.filter(row=>Number.isSafeInteger(row.costRuns) && row.costRuns>=5 && Number.isSafeInteger(row.costUsers) && row.costUsers>=3 && row.costUsers<=row.costRuns && Number.isFinite(row.medianNetCredits) && row.medianNetCredits>=0 && row.medianNetCredits<=Number.MAX_SAFE_INTEGER).map(row=>[`${row.entityId}@${row.version}:${row.digest}`,row]));
@@ -226,7 +235,10 @@ export function recommendProjectTypeCombinations({goal,requirements,handoffRequi
226
235
  const exactResults=resultMatches.filter(result=>result?.match.exact).length,semanticFitBonus=exactResults*2;
227
236
  const creatorHistory=selected.map(creatorFor).filter(Boolean);
228
237
  const creatorBonus=selected.length?creatorHistory.reduce((total,row)=>total+(row.completedRuns+1)/(row.terminalRuns+2)-0.5,0)/selected.length:0;
229
- const score=(coverage+handoffs.length-missingHandoffs.length)*1000-broken*300-missingSourceInputs.length*600-deviceIssues.length*300-audit.counts.questions*30-keys.length*10-approvals+usageBonus+preferenceBonus+semanticFitBonus+completionBonus+latencyBonus+costBonus+creatorBonus;
238
+ // Reviewed Blocks win ties over Community ones; widely installed Blocks win ties over new ones.
239
+ const installBonus=selected.length?selected.reduce((total,candidate)=>total+Math.min(1,Math.log1p(installsFor(candidate)||0)/Math.log1p(50)),0)/selected.length:0;
240
+ const communityPenalty=selected.filter(candidate=>candidate.origin==='community').length*0.5;
241
+ const score=(coverage+handoffs.length-missingHandoffs.length)*1000-broken*300-missingSourceInputs.length*600-deviceIssues.length*300-audit.counts.questions*30-keys.length*10-approvals+usageBonus+preferenceBonus+semanticFitBonus+completionBonus+latencyBonus+costBonus+creatorBonus+installBonus-communityPenalty;
230
242
  const resultAllocations=resultMatches.map((result,index)=>result?{requirement:wanted[index].key,stageId:connected.stages[result.candidateIndex].id,port:result.port,exact:result.match.exact,...(result.viaAction?{viaAction:result.viaAction,requestType:result.requestType}:{})}:null);
231
243
  return {keys,pinnedConnections,definition:connected,audit,missing,missingHandoffs,sourceInputs,missingSourceInputs,handoffPlan,resultAllocations,deviceSupport,deviceIssues,score,coverage,assemblyReady:broken===0&&missing.length===0&&missingHandoffs.length===0&&unavailableSourceInputs.length===0&&deviceIssues.length===0,compatible:broken===0 && missing.length===0 && missingHandoffs.length===0 && missingSourceInputs.length===0 && deviceIssues.length===0,explanation:{requiredResults:wanted.length,coveredResults:coverage,requiredHandoffs:handoffs.length,connectedHandoffs:handoffs.length-missingHandoffs.length,missingSourceInputs:missingSourceInputs.length,plannedActionResults:resultAllocations.filter(item=>item?.viaAction).length,exactResults,compatibleResults:coverage-exactResults,semanticFitBonus,connectionIssues:broken,questions:audit.counts.questions,permissionDeclarations:approvals,blockCount:keys.length,requestedExecutionDevices:executionDevices,declaredSupportedDeviceChecks:deviceSupport.length-deviceIssues.length,unknownDeviceChecks:deviceIssues.filter(item=>item.status==='undeclared').length,unsupportedDeviceChecks:deviceIssues.filter(item=>item.status==='declared-unsupported').length,observedUsageBlocks:observed.length,usageBonus,observedExecutionBlocks:measured.length,completionBonus,observedLatencyBlocks:timed.length,latencyBonus,latencyMetric:'hosted-created-to-completed-median',observedCostBlocks:priced.length,costBonus,costMetric:'verified-single-call-net-credits-median',observedCreatorBlocks:creatorHistory.length,creatorBonus,creatorMetric:'other-block-hosted-completion-history',localBlocks,executionPreference,preferenceBonus}};
232
244
  }
@@ -29,6 +29,9 @@ const SECTIONS=Object.freeze([
29
29
  rule('source-of-truth','both',
30
30
  'Use only documented SDK runtimes, types, operations, permissions and host APIs; never invent one.',
31
31
  'Treat the current SDK (`stillmade.block.json` manifest, `packages/block-sdk` contracts, validators, examples and published docs) as the source of truth. Before writing code, read the manifest contract, at least two working first-party Blocks closest to the request, the runtime you will use, the typed port and resolver contracts, and the shared-interface contract when you need a custom view. Do not invent runtimes, operations, permissions, ports, host services or bridge calls. If the documentation and the validator disagree, the validator wins and the mismatch should be reported.'),
32
+ rule('reuse-first','both',
33
+ 'Reuse before building: use, remix or chain an existing Block when one fits; build only what is missing.',
34
+ 'Before building, check what already exists (`find_existing_blocks` over MCP, or the Marketplace and your library) by the inputs, results and operations the goal needs. Use an installed or reviewed Block that already does it; remix a close one so its license, notices and creator credit stay attached; chain existing Blocks and build only the missing step. Never republish another creator\'s source without remix lineage: public copies are refused. Build a new Block when nothing fits or the person asks for their own version, and say which similar Blocks you considered.'),
32
35
  rule('capability-contract','block',
33
36
  'Define the contract first: typed inputs (optional with safe defaults where possible), outputs, state, permissions, UI, failures and cancellation. Keep it small.',
34
37
  'Translate the request into an explicit capability contract before implementation: what the Block does; each input with its type, meaning and whether it is required (prefer optional settings with safe defaults over extra required questions); each output with its type and meaning; persistent state; project context it reads; permissions; UI; long-running behavior; expected failures; cancellation; determinism; and whether it needs hosted models, media, desktop tools or shared editing. Keep the public interface as small and general as possible and keep implementation details out of it.'),
@@ -113,7 +116,7 @@ export const BUILDER_CONTRACT=Object.freeze({
113
116
  gapClasses:GAP_CLASSES,
114
117
  });
115
118
 
116
- const SECTION_TITLES=Object.freeze({'source-of-truth':'Source of truth','capability-contract':'Define the capability first','compose':'Blocks compose','platform-primitives':'Use platform primitives','no-workarounds':'No hidden workarounds','ui':'Interface','multiplayer':'Shared editing','external-services':'External services','dependencies':'Dependencies','security':'Security','lifecycle':'Execution lifecycle','errors':'Useful failures','adapt-to-platform':'Adapt to the platform','verification':'What StillMade verifies','project-types':'Project Types','readiness-report':'Readiness report'});
119
+ const SECTION_TITLES=Object.freeze({'source-of-truth':'Source of truth','reuse-first':'Reuse first','capability-contract':'Define the capability first','compose':'Blocks compose','platform-primitives':'Use platform primitives','no-workarounds':'No hidden workarounds','ui':'Interface','multiplayer':'Shared editing','external-services':'External services','dependencies':'Dependencies','security':'Security','lifecycle':'Execution lifecycle','errors':'Useful failures','adapt-to-platform':'Adapt to the platform','verification':'What StillMade verifies','project-types':'Project Types','readiness-report':'Readiness report'});
117
120
  const inScope=(scope,wanted)=>wanted==='all'||scope==='both'||scope===wanted;
118
121
 
119
122
  /** Render the contract for a model prompt ('compact'), a guide ('full') or an SDK folder ('agents-md'). */