@tomato414941/foundation 0.9.0 → 0.10.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.
Files changed (3) hide show
  1. package/guide.mjs +15 -1
  2. package/package.json +1 -1
  3. package/runtime.mjs +9 -5
package/guide.mjs CHANGED
@@ -134,8 +134,22 @@ export function guide(services) {
134
134
  ' Poll GET /v1/requests/<id> every few seconds until done; result.credential_id identifies the credential.',
135
135
  ' DELETE /v1/resources/<id> {"revoke": true|false} disconnects one (the owner, in a browser); revoke also asks the',
136
136
  ' service to withdraw what it granted. What was already handed out stays where it went.', '',
137
+ 'ENVIRONMENTS (a machine with a shell, for when you have none)',
138
+ ' A lent machine: a shell, files and the network, thrown away when done. By itself it reaches nothing of Foundation.',
139
+ ' Give it an identity - a principal you may act as (yourself, one you own, or one you act for) - and it holds that',
140
+ ' principal\'s key for its life: inside, the foundation CLI works as that principal (foundation exec, foundation api).',
141
+ ' POST /v1/environments {"identity":"<principal id>"|null, "size":"small|medium|large",',
142
+ ' "lifetime":{"end":"idle|exit","idle_seconds":600,"max_seconds":3600}} opens one; it is a resource (kind environment).',
143
+ ' POST /v1/environments/<id>/commands {"command":["npm","test"],"stdin":null,"timeout_seconds":300}',
144
+ ' runs one command: exit_code, stdout, stderr. 202 with status running if it takes longer; then',
145
+ ' GET /v1/environments/<id>/commands/<command id>. One command at a time; files persist between commands.',
146
+ ' PATCH /v1/environments/<id> {"identity":… or null} gives or takes away its identity. DELETE closes it.',
147
+ ' POST /v1/runs {…as opening, plus "command"} opens, runs one command, stops: the answer carries the result.',
148
+ ' What a command prints is cleaned of values handed in with injections. Keep what matters as an object.',
149
+ ' Computing is spent: GET /v1/principals/<id>/compute shows this month\'s use and limit; its owner may lower the',
150
+ ' limit with PUT {"monthly_seconds": n}. A medium machine spends twice its time, a large one four times.', '',
137
151
  'FUNCTIONS',
138
- ' GET /v1/functions catalog of built-in operations and their invocation endpoints; no arbitrary-code runtime.', '',
152
+ ' GET /v1/functions catalog of built-in operations and their invocation endpoints.', '',
139
153
  'WHEN IT DOES NOT WORK',
140
154
  ' GET /v1/requests/<id> one of your requests, and what happened at its page (events).',
141
155
  ' GET /v1/requests?status=pending your requests. Several may be open at once (up to 10).',
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tomato414941/foundation",
3
- "version": "0.9.0",
3
+ "version": "0.10.0",
4
4
  "description": "Foundation CLI: make a key, and hand what is kept to a command without it passing through the agent.",
5
5
  "type": "module",
6
6
  "engines": {
package/runtime.mjs CHANGED
@@ -233,11 +233,15 @@ async function main() {
233
233
  // Nothing runs before someone has accepted this key: a key that acts for nobody reaches only its own empty resources,
234
234
  // and the person it asked has yet to answer.
235
235
  const current = await send('/v1/principals/me', undefined, { method: 'GET' });
236
- if (!current.acts_for?.length) throw new Error('Foundation request failed (401, not_approved). This key acts for nobody yet' + (current.requests?.[0] ? '; it is waiting for approval at ' + current.requests[0].verification_uri : '') + '.');
237
- // Whose resources a run reaches: the one this key acts for, or the one named when it acts for several.
238
- const holder = process.env.FOUNDATION_AS || (current.acts_for.length === 1 ? current.acts_for[0].id : null);
239
- if (!holder) throw new Error('This key acts for several principals. Set FOUNDATION_AS=<principal id> to say which one this run is for.');
240
- const forHolder = target => target + (target.includes('?') ? '&' : '?') + 'as=' + encodeURIComponent(holder);
236
+ // A key given to a lent machine acts as its principal's own self. Any other key acts for someone once approved;
237
+ // until then, whether waiting or refused, it has nothing to run with.
238
+ const own = Boolean(current.key?.environment);
239
+ if (!own && !current.acts_for?.length) throw new Error('Foundation request failed (401, not_approved). This key acts for nobody yet' + (current.requests?.[0] ? '; it is waiting for approval at ' + current.requests[0].verification_uri : '') + '.');
240
+ // Whose resources a run reaches: the one this key acts for, the one named when it acts for several, or its own.
241
+ const acting = current.acts_for ?? [];
242
+ const holder = process.env.FOUNDATION_AS || (acting.length === 1 ? acting[0].id : null);
243
+ if (!holder && acting.length > 1) throw new Error('This key acts for several principals. Set FOUNDATION_AS=<principal id> to say which one this run is for.');
244
+ const forHolder = target => holder ? target + (target.includes('?') ? '&' : '?') + 'as=' + encodeURIComponent(holder) : target;
241
245
  let injection;
242
246
  if (names.length) ({ injection } = await send(forHolder('/v1/injections'), { names }));
243
247
  else injection = { environment: {}, files: [] };