@lapxo/head 0.0.0-stage → 0.1.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.
- package/LICENSE +21 -0
- package/TARGET.bound +443 -0
- package/dist/src/access/contract.d.ts +69 -0
- package/dist/src/access/contract.js +6 -0
- package/dist/src/access/obtain.d.ts +19 -0
- package/dist/src/access/obtain.js +70 -0
- package/dist/src/adopt/adopt.d.ts +12 -0
- package/dist/src/adopt/adopt.js +37 -0
- package/dist/src/compile/pin.d.ts +26 -0
- package/dist/src/compile/pin.js +74 -0
- package/dist/src/core/act.d.ts +17 -0
- package/dist/src/core/act.js +17 -0
- package/dist/src/core/answer.d.ts +90 -0
- package/dist/src/core/answer.js +23 -0
- package/dist/src/core/device.d.ts +26 -0
- package/dist/src/core/device.js +27 -0
- package/dist/src/core/keys.d.ts +14 -0
- package/dist/src/core/keys.js +20 -0
- package/dist/src/core/lock.d.ts +9 -0
- package/dist/src/core/lock.js +11 -0
- package/dist/src/core/read.d.ts +51 -0
- package/dist/src/core/read.js +60 -0
- package/dist/src/core/receipt.d.ts +13 -0
- package/dist/src/core/receipt.js +12 -0
- package/dist/src/core/surface.d.ts +45 -0
- package/dist/src/core/surface.js +32 -0
- package/dist/src/core/worlds.d.ts +10 -0
- package/dist/src/core/worlds.js +9 -0
- package/dist/src/flows/act.d.ts +7 -0
- package/dist/src/flows/act.js +43 -0
- package/dist/src/flows/answer.d.ts +12 -0
- package/dist/src/flows/answer.js +25 -0
- package/dist/src/flows/call.d.ts +50 -0
- package/dist/src/flows/call.js +76 -0
- package/dist/src/flows/device.d.ts +26 -0
- package/dist/src/flows/device.js +37 -0
- package/dist/src/flows/plan.d.ts +8 -0
- package/dist/src/flows/plan.js +51 -0
- package/dist/src/flows/read.d.ts +9 -0
- package/dist/src/flows/read.js +85 -0
- package/dist/src/flows/world.d.ts +12 -0
- package/dist/src/flows/world.js +29 -0
- package/dist/src/index.d.ts +2 -0
- package/dist/src/index.js +119 -0
- package/dist/src/places/admit.d.ts +7 -0
- package/dist/src/places/admit.js +32 -0
- package/dist/src/places/found.d.ts +6 -0
- package/dist/src/places/found.js +59 -0
- package/dist/src/ports/access/flow.d.ts +13 -0
- package/dist/src/ports/access/flow.js +120 -0
- package/dist/src/ports/access/page.d.ts +12 -0
- package/dist/src/ports/access/page.js +50 -0
- package/dist/src/ports/access/person.d.ts +25 -0
- package/dist/src/ports/access/person.js +34 -0
- package/dist/src/ports/adapters/request.d.ts +38 -0
- package/dist/src/ports/adapters/request.js +67 -0
- package/dist/src/ports/bound.d.ts +51 -0
- package/dist/src/ports/bound.js +68 -0
- package/dist/src/ports/cache.d.ts +4 -0
- package/dist/src/ports/cache.js +14 -0
- package/dist/src/ports/keychain.d.ts +7 -0
- package/dist/src/ports/keychain.js +11 -0
- package/dist/src/ports/place.d.ts +10 -0
- package/dist/src/ports/place.js +26 -0
- package/dist/src/ports/process.d.ts +20 -0
- package/dist/src/ports/process.js +49 -0
- package/dist/src/ports/signers.d.ts +6 -0
- package/dist/src/ports/signers.js +14 -0
- package/dist/src/ports/stores/credential-manager.d.ts +3 -0
- package/dist/src/ports/stores/credential-manager.js +22 -0
- package/dist/src/ports/stores/keychain.d.ts +3 -0
- package/dist/src/ports/stores/keychain.js +16 -0
- package/dist/src/ports/stores/secret-tool.d.ts +3 -0
- package/dist/src/ports/stores/secret-tool.js +16 -0
- package/dist/src/resources/view.d.ts +1 -0
- package/dist/src/resources/view.js +1 -0
- package/dist/src/signer.d.ts +2 -0
- package/dist/src/signer.js +14 -0
- package/dist/src/sources/access.d.ts +8 -0
- package/dist/src/sources/access.js +34 -0
- package/dist/src/sources/connect.d.ts +10 -0
- package/dist/src/sources/connect.js +68 -0
- package/dist/src/tools/access.d.ts +1 -0
- package/dist/src/tools/access.js +1 -0
- package/dist/src/tools/act.d.ts +1 -0
- package/dist/src/tools/act.js +1 -0
- package/dist/src/tools/admit.d.ts +1 -0
- package/dist/src/tools/admit.js +1 -0
- package/dist/src/tools/card.d.ts +3 -0
- package/dist/src/tools/card.js +13 -0
- package/dist/src/tools/connect.d.ts +1 -0
- package/dist/src/tools/connect.js +1 -0
- package/dist/src/tools/key.d.ts +3 -0
- package/dist/src/tools/key.js +11 -0
- package/dist/src/tools/land.d.ts +1 -0
- package/dist/src/tools/land.js +1 -0
- package/dist/src/tools/look.d.ts +8 -0
- package/dist/src/tools/look.js +40 -0
- package/dist/src/tools/place.d.ts +1 -0
- package/dist/src/tools/place.js +1 -0
- package/dist/src/tools/plan.d.ts +1 -0
- package/dist/src/tools/plan.js +1 -0
- package/dist/src/walk/context.d.ts +7 -0
- package/dist/src/walk/context.js +23 -0
- package/package.json +35 -4
- package/README.md +0 -3
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { extname, isAbsolute, resolve, sep } from 'node:path';
|
|
2
|
+
import { canonical, EXTENSION } from '@lapxo/topos/wire';
|
|
3
|
+
import { inPlace, unless } from "../core/answer.js";
|
|
4
|
+
import { valueOf } from "../core/lock.js";
|
|
5
|
+
import { vocabOf } from "../core/read.js";
|
|
6
|
+
import { redIn, sayIn } from "../core/surface.js";
|
|
7
|
+
import { digestIn } from "../core/worlds.js";
|
|
8
|
+
import { paidBy, pinIn } from "../compile/pin.js";
|
|
9
|
+
import { adopted } from "../adopt/adopt.js";
|
|
10
|
+
import { rootIn } from "../flows/device.js";
|
|
11
|
+
/** The kind a document is named by, never read for: its file's extension, its address's, or the media type it was served as; bytes that say none are octet-stream. */
|
|
12
|
+
const kindOf = (at, type = '') => (extname(URL.canParse(at) ? new URL(at).pathname : at).slice(1)
|
|
13
|
+
|| (type.split(';')[0].split('/')[1] ?? '').split('+').at(-1).replace(/^x-/, '') || 'octet-stream').toLowerCase();
|
|
14
|
+
/** A document the person names: an encrypted address, or a file inside the place or a folder the client shares; anything else is not read. */
|
|
15
|
+
const documentOf = async (context, place, at) => {
|
|
16
|
+
if (URL.canParse(at))
|
|
17
|
+
return ((got) => got && { bytes: got.bytes, kind: kindOf(at, got.type) })(await (await context.adapter(at))?.get(at, Number(valueOf(context.lock, 'adapter/request/wait').split('..')[1])));
|
|
18
|
+
const inside = [place, ...(await context.roots())].some((root) => resolve(at).startsWith(`${resolve(root)}${sep}`));
|
|
19
|
+
return ((bytes) => bytes && { bytes, kind: kindOf(at) })(isAbsolute(at) && inside ? context.files.take(at) : undefined);
|
|
20
|
+
};
|
|
21
|
+
/**
|
|
22
|
+
* A source connected to a place, once the person said yes; a lock is no source, and adopting one as a parent is refused
|
|
23
|
+
* by name, since composing two places' policies is bound's. A document — and an overlay beside it — is laid whatever its
|
|
24
|
+
* kind, with every world head carries adopted, and the fold decides which reads it: what no world compiles is open, the
|
|
25
|
+
* bytes taken back and the line that pays it handed on. What one does is compiled once per digest of what it read — the
|
|
26
|
+
* same bytes again find their compiled standing by name — and pinned from the place's store: a new pin lands with the
|
|
27
|
+
* old one's withdraw, said at its own time, since a withdrawn saying stays withdrawn.
|
|
28
|
+
*/
|
|
29
|
+
export const connected = (asked, context) => ((started) => inPlace(asked, context, async (place) => {
|
|
30
|
+
const say = sayIn(context.lock), v = vocabOf(context.lock), word = (k) => valueOf(context.lock, k), digest = digestIn(context.lock);
|
|
31
|
+
const [source, document] = [(asked['source'] ?? '').toLowerCase().replace(/[^a-z0-9-]+/g, '-'), asked['document'] ?? ''];
|
|
32
|
+
if (!source)
|
|
33
|
+
return [say('missing-param', { operation: 'connect', param: 'source' })];
|
|
34
|
+
if (`.${kindOf(document)}` === EXTENSION)
|
|
35
|
+
return [say('parent-lock', { place, parent: source })];
|
|
36
|
+
const root = rootIn(context, place);
|
|
37
|
+
if ('said' in root)
|
|
38
|
+
return root.said;
|
|
39
|
+
const refused = await unless(context, say('elicit-connect', { source, document, place, overlay: asked['overlay'] ?? '' }));
|
|
40
|
+
if (refused)
|
|
41
|
+
return refused;
|
|
42
|
+
const [doc, overlay] = [await documentOf(context, place, document), asked['overlay'] ? await documentOf(context, place, asked['overlay']) : undefined];
|
|
43
|
+
if (doc === undefined || (asked['overlay'] && overlay === undefined))
|
|
44
|
+
return [say('document-unread', { document })];
|
|
45
|
+
const lands = (lot) => context.landRoot(place, lot, root.account);
|
|
46
|
+
const line = (scope, measure, value, more = {}) => canonical({ at: 'policy:head/connect', by: 'target', form: 'alphabet', measure, role: 'writes', scope, value, ...more });
|
|
47
|
+
const pin = pinIn(context, place, lands, line);
|
|
48
|
+
if (`.${doc.kind}` === EXTENSION)
|
|
49
|
+
return [say('parent-lock', { place, parent: source })];
|
|
50
|
+
const worlds = await adopted(context, place, lands, line);
|
|
51
|
+
if ('refused' in worlds)
|
|
52
|
+
return [say('not-landed', { why: worlds.refused })];
|
|
53
|
+
const laid = [[`${word('place/connected')}/${source}.${doc.kind}`, doc.bytes], ...(overlay ? [[`${word('place/connected')}/${source}.overlay.${overlay.kind}`, overlay.bytes]] : [])];
|
|
54
|
+
for (const [at, bytes] of laid)
|
|
55
|
+
context.files.lay(place, at, bytes);
|
|
56
|
+
const pinned = await pin(source, laid.map(([at, bytes]) => `${at} ${digest(bytes)}`));
|
|
57
|
+
if ('said' in pinned) {
|
|
58
|
+
if (pinned.open || pinned.dropped)
|
|
59
|
+
for (const [at] of laid)
|
|
60
|
+
context.files.drop(place, at);
|
|
61
|
+
return pinned.open ? [say('no-world', { kind: doc.kind, document }), line(`${word('place/needs')}/${doc.kind}`, 'id', valueOf(context.lock, 'birth/view/place'), { role: 'demands' })] : pinned.said;
|
|
62
|
+
}
|
|
63
|
+
const [owed, paid] = [pinned.lines.filter((l) => l.measure === v.unresolved).map((l) => l.value ?? ''), await paidBy(context, place, pin, laid[0][0])];
|
|
64
|
+
const classes = pinned.lines.filter((l) => l.measure === v.class && l.scope?.startsWith(`${v.offers}/${source}/`) && l.scope.split('/').length === 3);
|
|
65
|
+
return [say('connected', { source, place, offers: String(classes.length), reads: String(classes.filter((l) => l.value === v.callable).length), pin: pinned.pin }),
|
|
66
|
+
...(owed.length ? [say('unresolved', { source, refs: owed.join(', ') })] : []), ...paid.flatMap((p) => ('said' in p.pinned ? p.pinned.said : [say('resolved', { source: p.source, by: source, pin: p.pinned.pin })])),
|
|
67
|
+
...pinned.lines.filter((l) => l.scope === `${v.region}/${source}` || (l.scope?.startsWith(`${v.keys}/${source}/`) && l.measure === v.scheme)).map((l) => canonical(l))];
|
|
68
|
+
}).then((lines) => [...lines, ...redIn(context.lock)('connect/seconds', `connect/${asked['source'] ?? ''}`, started, context.machine())]))(context.machine());
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { accessed as answer } from '../sources/access.ts';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { accessed as answer } from "../sources/access.js";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { act as answer } from '../flows/act.ts';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { act as answer } from "../flows/act.js";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { admitted as answer } from '../places/admit.ts';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { admitted as answer } from "../places/admit.js";
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { inPlace, printedOr, standingOr } from "../core/answer.js";
|
|
2
|
+
import { aboutOf, members, valueOf } from "../core/lock.js";
|
|
3
|
+
/** What is open for a key: the cells view the place's standing declares, as bound folded it, narrowed to the key; a refused fold is said, never read as no view. */
|
|
4
|
+
export const answer = (asked, context) => inPlace(asked, context, async (place) => {
|
|
5
|
+
const word = (scope) => valueOf(context.lock, `bound/${scope}`);
|
|
6
|
+
const held = await standingOr(context, place);
|
|
7
|
+
if ('said' in held)
|
|
8
|
+
return held.said;
|
|
9
|
+
const view = held.lines.find((f) => f.scope?.startsWith('view/') && !f.shape && members(f.value ?? '').includes(word('cells')));
|
|
10
|
+
if (view === undefined)
|
|
11
|
+
return [aboutOf(context.lock, 'said/no-cells')];
|
|
12
|
+
return printedOr(context, await context.bound(place, [word('read'), word('view'), view.scope.split('/')[1], ...(asked['key'] ? [word('key'), asked['key']] : [])]));
|
|
13
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { connected as answer } from '../sources/connect.ts';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { connected as answer } from "../sources/connect.js";
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { admissionOf, deviceOf } from "../core/device.js";
|
|
2
|
+
import { aboutOf } from "../core/lock.js";
|
|
3
|
+
import { deviceKey } from "../flows/device.js";
|
|
4
|
+
/** The lines that admit this device: its key is read from the keychain, or made there once; only its public half goes out. */
|
|
5
|
+
export const answer = async (asked, context) => {
|
|
6
|
+
const role = asked['who'] || undefined;
|
|
7
|
+
if (!deviceOf(context.lock, role).account)
|
|
8
|
+
return [aboutOf(context.lock, 'said/no-role')];
|
|
9
|
+
const key = deviceKey(context, role);
|
|
10
|
+
return key === undefined ? [aboutOf(context.lock, 'said/no-keychain')] : admissionOf(context.lock, key, role);
|
|
11
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { landLot as answer } from '../flows/plan.ts';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { landLot as answer } from "../flows/plan.js";
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { Answer } from '../core/answer.ts';
|
|
2
|
+
/**
|
|
3
|
+
* One view of a place, folded by bound at the resolution asked; or, of a source, what it offers as typed lines — at the
|
|
4
|
+
* first resolution where it is reached and each offer's class, by default its forms and how access is proven too, never
|
|
5
|
+
* what only a transport reads — and, at the call resolution, one read of an offer of the class head reads. Each answer
|
|
6
|
+
* is measured against answer/seconds and reads red past it, with the question it answered as its coordinate.
|
|
7
|
+
*/
|
|
8
|
+
export declare const answer: Answer;
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { canonical } from '@lapxo/topos/wire';
|
|
2
|
+
import { inPlace, printedOr } from "../core/answer.js";
|
|
3
|
+
import { valueOf } from "../core/lock.js";
|
|
4
|
+
import { vocabOf } from "../core/read.js";
|
|
5
|
+
import { redIn, sayIn } from "../core/surface.js";
|
|
6
|
+
import { readSource } from "../flows/read.js";
|
|
7
|
+
import { standingFor } from "../flows/world.js";
|
|
8
|
+
/**
|
|
9
|
+
* One view of a place, folded by bound at the resolution asked; or, of a source, what it offers as typed lines — at the
|
|
10
|
+
* first resolution where it is reached and each offer's class, by default its forms and how access is proven too, never
|
|
11
|
+
* what only a transport reads — and, at the call resolution, one read of an offer of the class head reads. Each answer
|
|
12
|
+
* is measured against answer/seconds and reads red past it, with the question it answered as its coordinate.
|
|
13
|
+
*/
|
|
14
|
+
export const answer = (asked, context) => ((started) => inPlace(asked, context, async (place) => {
|
|
15
|
+
const word = (scope) => valueOf(context.lock, scope);
|
|
16
|
+
const source = asked['source'];
|
|
17
|
+
if (source) {
|
|
18
|
+
if (asked['operation'] && (asked['at'] === word('look/call') || asked['history'] === 'true'))
|
|
19
|
+
return readSource(asked, context);
|
|
20
|
+
const held = await standingFor(context, place);
|
|
21
|
+
if ('unsettled' in held)
|
|
22
|
+
return [sayIn(context.lock)('unsettled', { source, why: held.unsettled })];
|
|
23
|
+
const [v, first, shallow] = [vocabOf(context.lock), (asked['at'] ?? word('look/default')) === '0', word('look/first').split('|')];
|
|
24
|
+
const offer = `${v.offers}/${source}/${asked['operation'] ?? ''}`;
|
|
25
|
+
const shown = held.lines.filter((l) => {
|
|
26
|
+
const scope = l.scope ?? '';
|
|
27
|
+
if (scope === `${v.region}/${source}`)
|
|
28
|
+
return true;
|
|
29
|
+
if (scope.startsWith(`${v.keys}/${source}/`))
|
|
30
|
+
return !first;
|
|
31
|
+
const ofOffer = asked['operation'] ? scope === offer || scope.startsWith(`${offer}/`) : scope.startsWith(offer);
|
|
32
|
+
if (!ofOffer || scope.endsWith(`/${v.carry}`))
|
|
33
|
+
return false;
|
|
34
|
+
return !first || (!scope.endsWith(`/${v.form}`) && shallow.includes(l.measure ?? ''));
|
|
35
|
+
});
|
|
36
|
+
return shown.length ? shown.map((l) => canonical(l)).sort() : [sayIn(context.lock)('unread', { source })];
|
|
37
|
+
}
|
|
38
|
+
const view = `${asked['view'] || word('bound/standing')}${asked['at'] ? `${word('bound/at')}${asked['at']}` : ''}`;
|
|
39
|
+
return printedOr(context, await context.bound(place, [word('bound/read'), word('bound/view'), view]));
|
|
40
|
+
}).then((lines) => [...lines, ...redIn(context.lock)('answer/seconds', `answer/${asked['source'] ? `${asked['source']}/${asked['operation'] ?? ''}` : asked['view'] || valueOf(context.lock, 'bound/standing')}@${asked['at'] ?? valueOf(context.lock, 'look/default')}`, started, context.machine())]))(context.machine());
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { bornPlace as answer } from '../places/found.ts';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { bornPlace as answer } from "../places/found.js";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { planLot as answer } from '../flows/plan.ts';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { planLot as answer } from "../flows/plan.js";
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { Context, Outcome } from '../core/answer.ts';
|
|
2
|
+
/**
|
|
3
|
+
* A place made walkable once it is founded: the context another place authenticates it by — its wire, its keys and its
|
|
4
|
+
* origin, read off the lines it was born with — folded by bound into a standing, laid beside its lock and pinned by its
|
|
5
|
+
* root, so a peer selects it by digest. Its history is offered only as its walk view declares, and only when its own key walks it.
|
|
6
|
+
*/
|
|
7
|
+
export declare const walkable: (context: Context, dir: string, account: string) => Promise<Outcome>;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { join } from 'node:path';
|
|
2
|
+
import { canonical, LOCK } from '@lapxo/topos/wire';
|
|
3
|
+
import { members, valueOf } from "../core/lock.js";
|
|
4
|
+
import { linesOf } from "../core/worlds.js";
|
|
5
|
+
/**
|
|
6
|
+
* A place made walkable once it is founded: the context another place authenticates it by — its wire, its keys and its
|
|
7
|
+
* origin, read off the lines it was born with — folded by bound into a standing, laid beside its lock and pinned by its
|
|
8
|
+
* root, so a peer selects it by digest. Its history is offered only as its walk view declares, and only when its own key walks it.
|
|
9
|
+
*/
|
|
10
|
+
export const walkable = async (context, dir, account) => {
|
|
11
|
+
const [word, at] = [(k) => valueOf(context.lock, k), valueOf(context.lock, 'walk/context/file')];
|
|
12
|
+
const reads = members(word('walk/context/reads'));
|
|
13
|
+
const born = linesOf(context.files.take(join(dir, LOCK)) ?? new Uint8Array()).filter((l) => reads.some((r) => (r.endsWith('/**') ? l.scope?.startsWith(r.slice(0, -2)) : l.scope === r)) && l.value !== 'withdraw');
|
|
14
|
+
const draft = at.replace(/\.bound$/, '.draft.bound');
|
|
15
|
+
context.files.lay(dir, draft, new TextEncoder().encode(`${[...born.map(({ sig: _s, epoch: _e, ...l }) => canonical({ ...l, by: 'target' })),
|
|
16
|
+
canonical({ at: 'policy:head/walk', by: 'target', form: 'alphabet', measure: 'reads', role: 'writes', scope: word('walk/context/region'), value: reads.join('|') })].join('\n')}\n`));
|
|
17
|
+
const pinned = await context.pinned(dir, draft);
|
|
18
|
+
context.files.drop(dir, draft);
|
|
19
|
+
if (pinned === undefined || 'refused' in pinned)
|
|
20
|
+
return { refused: pinned === undefined ? 'walk context folded nothing' : pinned.refused };
|
|
21
|
+
context.files.lay(dir, at, new TextEncoder().encode(pinned.bytes));
|
|
22
|
+
return context.landRoot(dir, [canonical({ at: 'policy:head/walk', by: 'target', form: 'alphabet', measure: 'digest', needs: at, role: 'writes', scope: 'walk/context', value: pinned.pin })], account);
|
|
23
|
+
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,37 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lapxo/head",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"
|
|
5
|
-
"description": "
|
|
6
|
-
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"type": "module",
|
|
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
|
+
"license": "MIT",
|
|
7
|
+
"repository": {
|
|
8
|
+
"type": "git",
|
|
9
|
+
"url": "git+https://github.com/Lapxo/head.git"
|
|
10
|
+
},
|
|
11
|
+
"author": "Lapxo",
|
|
12
|
+
"engines": {
|
|
13
|
+
"node": ">=22.18"
|
|
14
|
+
},
|
|
15
|
+
"bin": {
|
|
16
|
+
"head": "./dist/src/index.js"
|
|
17
|
+
},
|
|
18
|
+
"files": [
|
|
19
|
+
"dist/src",
|
|
20
|
+
"TARGET.bound",
|
|
21
|
+
"LICENSE"
|
|
22
|
+
],
|
|
23
|
+
"scripts": {
|
|
24
|
+
"build": "tsc -p . --incremental false --tsBuildInfoFile null",
|
|
25
|
+
"prepack": "npm run build",
|
|
26
|
+
"test": "node --test test/*.test.ts"
|
|
27
|
+
},
|
|
28
|
+
"dependencies": {
|
|
29
|
+
"@lapxo/bound": "0.1.6",
|
|
30
|
+
"@lapxo/topos": "0.1.12",
|
|
31
|
+
"@modelcontextprotocol/sdk": "1.32.1"
|
|
32
|
+
},
|
|
33
|
+
"devDependencies": {
|
|
34
|
+
"@types/node": "22.20.5",
|
|
35
|
+
"typescript": "5.9.3"
|
|
36
|
+
}
|
|
37
|
+
}
|
package/README.md
DELETED