@lapxo/head 0.1.7 → 0.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.
@@ -1,8 +1,9 @@
1
- import { inStanding, printedOr } from "../core/answer.js";
1
+ import { authorityFor } from "../flows/plan.js";
2
+ import { inStanding, inPlace, printedOr } from "../core/answer.js";
2
3
  import { members, valueOf } from "../core/lock.js";
3
4
  import { sayIn } from "../core/surface.js";
4
5
  /** What is open for a key: the cells view the place's standing declares, as bound folded it at the resolution asked, narrowed to the key; a refused fold is said, never read as no view. The standing is the one the card was read off, folded once a call. */
5
- export const answer = (asked, context) => inStanding(asked, context, async (place, lines) => {
6
+ export const answer = (asked, context) => asked['lines'] !== undefined || asked['preflight'] !== undefined || asked['authority'] !== undefined ? inPlace(asked, context, async (place) => (await authorityFor(context, place, asked['key'] ?? '', asked['preflight'] ?? 'record-coverage', (asked['lines'] ?? '').split('\n').filter(Boolean), true, asked['authority']))) : inStanding(asked, context, async (place, lines) => {
6
7
  const word = (scope) => valueOf(context.lock, `bound/${scope}`);
7
8
  const view = lines.find((f) => f.scope?.startsWith('view/') && !f.shape && members(f.value ?? '').includes(word('cells')));
8
9
  if (view === undefined)
@@ -5,16 +5,16 @@ import { sayIn } from "../core/surface.js";
5
5
  /** The words of a name as a person or a model says it: its runs of letters and digits, lowercase. */
6
6
  const words = (text) => text.toLowerCase().split(/[^a-z0-9]+/).filter(Boolean);
7
7
  /** The offers of a source a place holds: head's own registry of it, local, never sent to the model whole. */
8
- export const offersOf = (lock, lines, source) => ((at) => lines.filter((l) => l.measure === vocabOf(lock).class && l.scope?.startsWith(at)).map((l) => l.scope.slice(at.length)))(`${vocabOf(lock).offers}/${source}/`);
8
+ export const offersOf = (lock, lines, source) => ((v) => ((at) => lines.filter((l) => l.measure === v.class && l.scope?.startsWith(at)).map((l) => l.scope.slice(at.length)))(`${v.offers}/${source}/`))(vocabOf(lock));
9
9
  /** Resolve the offer against the local registry. Ambiguity asks the person; read-ahead creates no use line. */
10
10
  export const namedIn = async (context, lines, source, asked, ahead) => {
11
11
  const [v, word, say] = [vocabOf(context.lock), (k) => valueOf(context.lock, k), sayIn(context.lock)];
12
- const [family, name] = [word('use/family'), words(asked).join('-')], uses = lines.filter((l) => l.scope?.startsWith(`${family}/${source}/`)), offers = offersOf(context.lock, lines, source);
12
+ const [family, name] = [word('use/family'), words(asked).join('-')], uses = lines.filter((l) => l.scope?.startsWith(`${family}/${source}/`));
13
13
  const used = uses.find((l) => l.scope === `${family}/${source}/${name}`)?.value;
14
14
  if (used !== undefined || ahead || !asked)
15
15
  return { operation: used ?? asked };
16
16
  const named = (op) => words([op, ...lines.filter((l) => l.scope === `${v.offers}/${source}/${op}/${v.carry}`).map((l) => l.value ?? '')].join(' '));
17
- const found = offers.includes(asked) ? [asked] : offers.filter((op) => words(asked).length > 0 && words(asked).every((w) => named(op).includes(w)));
17
+ const found = ((offers) => offers.includes(asked) ? [asked] : offers.filter((op) => words(asked).length > 0 && words(asked).every((w) => named(op).includes(w))))(offersOf(context.lock, lines, source));
18
18
  const operation = found.length > 1 ? (await context.person.choose(say('pick-offer', { source, asked }), [{ name: family, options: found.map((o) => ({ value: o, label: o })) }]))?.[family] : found[0];
19
19
  if (!found.length)
20
20
  return { operation: asked };
@@ -22,7 +22,7 @@ export const asked = async (asked, context) => {
22
22
  const owed = asked['source'] && founded ? await paidIn(asked, context, place) : undefined;
23
23
  if (owed !== undefined && !owed.answer)
24
24
  return owed.said;
25
- const answer = asked['sources'] && founded ? await compared(asked, context, place) : asked['lines'] ? await read('plan', 'plan') : founded && asked['view'] === valueOf(context.lock, 'claim/view') ? await viewed(asked, context) : asked['view'] ? await read('view', 'look') : asked['source'] ? await read('offers', 'look')
25
+ const answer = carded && (asked['lines'] !== undefined || asked['preflight'] !== undefined || asked['authority'] !== undefined) ? await read('card', 'card', { place }) : asked['sources'] && founded ? await compared(asked, context, place) : asked['lines'] ? await read('plan', 'plan') : founded && asked['view'] === valueOf(context.lock, 'claim/view') ? await viewed(asked, context) : asked['view'] ? await read('view', 'look') : asked['source'] ? await read('offers', 'look')
26
26
  : !carded ? await read('places', 'places') : founded ? [...await read('card', 'card', { place }), ...await pendingIn(context, place)] : [];
27
27
  const after = held === undefined || 'said' in held || place === undefined || !context.moved(place) ? held : await cardAt(context, place);
28
28
  return [...(owed?.said ?? []), ...answer, ...(after === undefined || 'said' in after ? [] : [sayIn(context.lock)('card', { place: place ?? '', card: after.card, from: 'ask' })])];
@@ -11,6 +11,6 @@ export const cardAt = async (context, place) => {
11
11
  const held = place === undefined || !context.files.has(place, LOCK) ? { lines: [] } : await standingOr(context, place);
12
12
  if ('said' in held)
13
13
  return held;
14
- const read = `${valueOf(context.lock, 'receipt/at')}:`, keys = ['head', 'person'].map((role) => context.device(role) ?? '');
15
- return { card: createHash('sha256').update([baseOf(held.lines.filter((l) => !l.at?.startsWith(read) && !l.scope?.startsWith(`${valueOf(context.lock, 'use/family')}/`))), ...keys].join('\n')).digest('hex').slice(0, 16) };
14
+ const read = `${valueOf(context.lock, 'receipt/at')}:`, use = `${valueOf(context.lock, 'use/family')}/`, keys = ['head', 'person'].map((role) => context.device(role) ?? '');
15
+ return { card: createHash('sha256').update([baseOf(held.lines.filter((l) => !l.at?.startsWith(read) && !l.scope?.startsWith(use))), ...keys].join('\n')).digest('hex').slice(0, 16) };
16
16
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lapxo/head",
3
- "version": "0.1.7",
3
+ "version": "0.2.0",
4
4
  "type": "module",
5
5
  "description": "An MCP server that folds: it runs bound as a process, hands a model what bound printed, and lands what it read as receipts.",
6
6
  "license": "MIT",
@@ -26,7 +26,7 @@
26
26
  "test": "node --test test/*.test.ts && node --test --test-concurrency=1 test/time/*.test.ts"
27
27
  },
28
28
  "dependencies": {
29
- "@lapxo/bound": "0.2.7",
29
+ "@lapxo/bound": "0.2.8",
30
30
  "@lapxo/topos": "0.2.4",
31
31
  "@modelcontextprotocol/sdk": "1.32.1"
32
32
  },
@@ -1,8 +0,0 @@
1
- import type { Printed } from './process.ts';
2
- /** Only the installed instrument names a view's identity and the result bound to it. */
3
- export declare const readingOf: (printed: Printed | undefined, view: string, expected?: string) => {
4
- readonly identity: string;
5
- readonly text?: string;
6
- } | {
7
- readonly refused: string;
8
- };
@@ -1,14 +0,0 @@
1
- /** Only the installed instrument names a view's identity and the result bound to it. */
2
- export const readingOf = (printed, view, expected) => {
3
- if (!printed || printed.code !== 0)
4
- return { refused: printed?.refusal?.['code'] ?? 'reading-identity/unavailable' };
5
- try {
6
- const value = printed.out.length === 1 ? JSON.parse(printed.out[0]) : undefined;
7
- if (value?.['kind'] !== 'fact' || value['view'] !== view || typeof value['identity'] !== 'string' || !/^sha256:[0-9a-f]{64}$/.test(value['identity']) || (expected !== undefined && (value['identity'] !== expected || typeof value['text'] !== 'string')))
8
- return { refused: 'reading-identity/context' };
9
- return { identity: value['identity'], ...(expected === undefined ? {} : { text: value['text'] }) };
10
- }
11
- catch {
12
- return { refused: 'reading-identity/format' };
13
- }
14
- };