@treenity/core 3.0.0 → 3.0.1
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/README.md +78 -0
- package/dist/chain.d.ts +3 -4
- package/dist/chain.d.ts.map +1 -1
- package/dist/chain.js.map +1 -1
- package/dist/client/trpc.d.ts.map +1 -1
- package/dist/client/trpc.js +1 -0
- package/dist/client/trpc.js.map +1 -1
- package/dist/comp/index.d.ts +3 -4
- package/dist/comp/index.d.ts.map +1 -1
- package/dist/comp/index.js +5 -4
- package/dist/comp/index.js.map +1 -1
- package/dist/comp/needs.d.ts.map +1 -1
- package/dist/comp/needs.js +3 -3
- package/dist/comp/needs.js.map +1 -1
- package/dist/core/component.d.ts +10 -8
- package/dist/core/component.d.ts.map +1 -1
- package/dist/core/component.js +4 -8
- package/dist/core/component.js.map +1 -1
- package/dist/core/context.d.ts +2 -2
- package/dist/core/context.d.ts.map +1 -1
- package/dist/core/path.d.ts.map +1 -1
- package/dist/core/path.js +7 -3
- package/dist/core/path.js.map +1 -1
- package/dist/core/registry.d.ts +2 -1
- package/dist/core/registry.d.ts.map +1 -1
- package/dist/core/registry.js.map +1 -1
- package/dist/core.d.ts +1 -1
- package/dist/core.d.ts.map +1 -1
- package/dist/core.js +1 -1
- package/dist/core.js.map +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -0
- package/dist/log.d.ts +30 -0
- package/dist/log.d.ts.map +1 -1
- package/dist/log.js +119 -0
- package/dist/log.js.map +1 -1
- package/dist/mod/examples/ticker/service.js +2 -3
- package/dist/mod/examples/ticker/service.js.map +1 -1
- package/dist/mod/index.d.ts +1 -1
- package/dist/mod/index.d.ts.map +1 -1
- package/dist/mod/index.js +1 -1
- package/dist/mod/index.js.map +1 -1
- package/dist/mod/loader.d.ts +1 -0
- package/dist/mod/loader.d.ts.map +1 -1
- package/dist/mod/loader.js +27 -1
- package/dist/mod/loader.js.map +1 -1
- package/dist/mods/clients.d.ts +2 -0
- package/dist/mods/clients.d.ts.map +1 -0
- package/dist/mods/clients.js +3 -0
- package/dist/mods/clients.js.map +1 -0
- package/dist/mods/llm/index.js +1 -1
- package/dist/mods/llm/index.js.map +1 -1
- package/dist/mods/mcp/server.d.ts +0 -1
- package/dist/mods/mcp/server.js +0 -1
- package/dist/mods/mcp/service.d.ts +0 -1
- package/dist/mods/mcp/service.js +0 -1
- package/dist/mods/mcp/types.d.ts +0 -1
- package/dist/mods/mcp/types.js +0 -1
- package/dist/mods/servers.d.ts +4 -0
- package/dist/mods/servers.d.ts.map +1 -0
- package/dist/mods/servers.js +5 -0
- package/dist/mods/servers.js.map +1 -0
- package/dist/mods/treenity/builtins.d.ts +2 -0
- package/dist/mods/treenity/builtins.d.ts.map +1 -0
- package/dist/mods/treenity/builtins.js +18 -0
- package/dist/mods/treenity/builtins.js.map +1 -0
- package/dist/mods/treenity/logs.d.ts +18 -0
- package/dist/mods/treenity/logs.d.ts.map +1 -0
- package/dist/mods/treenity/logs.js +17 -0
- package/dist/mods/treenity/logs.js.map +1 -0
- package/dist/mods/treenity/seed.js +29 -27
- package/dist/mods/treenity/seed.js.map +1 -1
- package/dist/mods/treenity/server.d.ts +2 -0
- package/dist/mods/treenity/server.d.ts.map +1 -1
- package/dist/mods/treenity/server.js +2 -0
- package/dist/mods/treenity/server.js.map +1 -1
- package/dist/mods/uix/client.js +4 -4
- package/dist/mods/uix/client.js.map +1 -1
- package/dist/mods/uix/compile.d.ts.map +1 -1
- package/dist/mods/uix/compile.js +4 -2
- package/dist/mods/uix/compile.js.map +1 -1
- package/dist/schema/_test-fixture.d.ts +11 -0
- package/dist/schema/_test-fixture.d.ts.map +1 -0
- package/dist/schema/_test-fixture.js +8 -0
- package/dist/schema/_test-fixture.js.map +1 -0
- package/dist/schema/types.d.ts +1 -0
- package/dist/schema/types.d.ts.map +1 -1
- package/dist/server/actions.js +1 -1
- package/dist/server/auth.d.ts.map +1 -1
- package/dist/server/auth.js +4 -3
- package/dist/server/auth.js.map +1 -1
- package/dist/server/client.d.ts +10 -3
- package/dist/server/client.d.ts.map +1 -1
- package/dist/server/client.js +1 -1
- package/dist/server/client.js.map +1 -1
- package/dist/server/doc-index.d.ts.map +1 -1
- package/dist/server/doc-index.js +13 -12
- package/dist/server/doc-index.js.map +1 -1
- package/dist/server/factory.d.ts +6 -0
- package/dist/server/factory.d.ts.map +1 -1
- package/dist/server/factory.js +44 -25
- package/dist/server/factory.js.map +1 -1
- package/dist/server/main.d.ts +0 -4
- package/dist/server/main.d.ts.map +1 -1
- package/dist/server/main.js +4 -30
- package/dist/server/main.js.map +1 -1
- package/dist/server/mcp.d.ts +0 -1
- package/dist/server/mcp.js +0 -1
- package/dist/server/migrate.js +3 -3
- package/dist/server/migrate.js.map +1 -1
- package/dist/server/mods-mount.d.ts +0 -1
- package/dist/server/mods-mount.d.ts.map +1 -1
- package/dist/server/mods-mount.js +0 -1
- package/dist/server/mods-mount.js.map +1 -1
- package/dist/server/mount-adapters.js +9 -4
- package/dist/server/mount-adapters.js.map +1 -1
- package/dist/server/prefab.d.ts +2 -2
- package/dist/server/prefab.d.ts.map +1 -1
- package/dist/server/prefab.js +4 -2
- package/dist/server/prefab.js.map +1 -1
- package/dist/server/refs.d.ts +3 -0
- package/dist/server/refs.d.ts.map +1 -0
- package/dist/server/refs.js +59 -0
- package/dist/server/refs.js.map +1 -0
- package/dist/server/server.d.ts.map +1 -1
- package/dist/server/server.js +13 -3
- package/dist/server/server.js.map +1 -1
- package/dist/server/sub.js.map +1 -1
- package/dist/server/trpc.d.ts +7 -0
- package/dist/server/trpc.d.ts.map +1 -1
- package/dist/server/trpc.js +6 -2
- package/dist/server/trpc.js.map +1 -1
- package/dist/tree/fs.d.ts.map +1 -1
- package/dist/tree/fs.js +20 -18
- package/dist/tree/fs.js.map +1 -1
- package/dist/tree/index.d.ts.map +1 -1
- package/dist/tree/index.js +2 -1
- package/dist/tree/index.js.map +1 -1
- package/dist/tree-chain.d.ts +2 -1
- package/dist/tree-chain.d.ts.map +1 -1
- package/dist/tree-chain.js +5 -3
- package/dist/tree-chain.js.map +1 -1
- package/dist/uri.d.ts.map +1 -1
- package/dist/uri.js +8 -3
- package/dist/uri.js.map +1 -1
- package/package.json +48 -6
- package/src/chain.ts +7 -5
- package/src/client/trpc.ts +1 -0
- package/src/comp/index.test.ts +45 -9
- package/src/comp/index.ts +19 -8
- package/src/comp/needs.ts +3 -3
- package/src/core/component.ts +16 -14
- package/src/core/context.ts +4 -4
- package/src/core/index.test.ts +22 -1
- package/src/core/path.ts +6 -3
- package/src/core/registry.ts +4 -7
- package/src/core.ts +1 -1
- package/src/index.ts +1 -0
- package/src/log.ts +172 -1
- package/src/mod/docs/07-realtime.md +19 -11
- package/src/mod/docs/08-services.md +10 -8
- package/src/mod/docs/10-acl.md +1 -1
- package/src/mod/docs/12-conventions.md +43 -0
- package/src/mod/docs/13-example.md +36 -26
- package/src/mod/docs/14-mod-format.md +81 -8
- package/src/mod/examples/ticker/service.ts +2 -3
- package/src/mod/index.ts +1 -1
- package/src/mod/loader.test.ts +53 -1
- package/src/mod/loader.ts +34 -1
- package/src/mods/clients.ts +2 -0
- package/src/mods/llm/index.ts +1 -1
- package/src/mods/servers.ts +4 -0
- package/src/mods/treenity/builtins.ts +21 -0
- package/src/mods/treenity/logs.ts +26 -0
- package/src/mods/treenity/seed.ts +30 -28
- package/src/mods/treenity/server.ts +2 -0
- package/src/mods/uix/client.ts +4 -4
- package/src/mods/uix/compile.ts +4 -2
- package/src/schema/_test-fixture.ts +12 -0
- package/src/schema/generated/ai.agent.json +133 -0
- package/src/schema/generated/ai.approval.json +105 -0
- package/src/schema/generated/ai.approvals.json +24 -0
- package/src/schema/generated/ai.assignment.json +28 -0
- package/src/schema/generated/ai.plan.json +84 -0
- package/src/schema/generated/ai.policy.json +105 -0
- package/src/schema/generated/ai.pool.json +37 -0
- package/src/schema/generated/ai.thread.json +64 -0
- package/src/schema/generated/board.kanban.json +7 -0
- package/src/schema/generated/canary.item.json +40 -0
- package/src/schema/generated/claude-search.json +20 -0
- package/src/schema/generated/craft.product.json +47 -0
- package/src/schema/generated/craft.shop.json +94 -0
- package/src/schema/generated/craft.subscription.json +27 -0
- package/src/schema/generated/examples.demo.sensor.reading.json +25 -0
- package/src/schema/generated/flow.node.action.json +61 -0
- package/src/schema/generated/flow.node.code.json +43 -0
- package/src/schema/generated/flow.node.condition.json +37 -0
- package/src/schema/generated/flow.node.end.json +35 -0
- package/src/schema/generated/flow.node.http.json +65 -0
- package/src/schema/generated/flow.node.llm.json +67 -0
- package/src/schema/generated/flow.node.loop.json +49 -0
- package/src/schema/generated/flow.node.start.json +39 -0
- package/src/schema/generated/flow.scenario.json +118 -0
- package/src/schema/generated/grove.attempt.json +199 -0
- package/src/schema/generated/grove.path.json +93 -0
- package/src/schema/generated/grove.review.json +27 -0
- package/src/schema/generated/grove.task.json +164 -0
- package/src/schema/generated/intel.scenario.json +58 -0
- package/src/schema/generated/intel.signal.json +113 -0
- package/src/schema/generated/intel.world.json +15 -0
- package/src/schema/generated/landing.block.json +201 -0
- package/src/schema/generated/landing.page.json +84 -0
- package/src/schema/generated/metatron.config.json +119 -0
- package/src/schema/generated/metatron.permission.json +36 -0
- package/src/schema/generated/metatron.skill.json +36 -0
- package/src/schema/generated/metatron.task.json +114 -0
- package/src/schema/generated/metatron.template.json +26 -0
- package/src/schema/generated/metatron.workspace.json +60 -0
- package/src/schema/generated/order.status.json +21 -0
- package/src/schema/generated/polyhope.backtest.json +161 -0
- package/src/schema/generated/polyhope.feed.json +33 -0
- package/src/schema/generated/polyhope.run.json +94 -0
- package/src/schema/generated/polyhope.strategy.json +152 -0
- package/src/schema/generated/polymax.activity.json +65 -0
- package/src/schema/generated/polymax.aggr-feed.json +28 -0
- package/src/schema/generated/polymax.aggr.json +20 -0
- package/src/schema/generated/polymax.alert.json +56 -0
- package/src/schema/generated/polymax.bot-config.json +14 -0
- package/src/schema/generated/polymax.bot-status.json +35 -0
- package/src/schema/generated/polymax.classification.json +55 -0
- package/src/schema/generated/polymax.deposits.json +45 -0
- package/src/schema/generated/polymax.holding.json +55 -0
- package/src/schema/generated/polymax.identity.json +71 -0
- package/src/schema/generated/polymax.lb-entry.json +75 -0
- package/src/schema/generated/polymax.leaderboard.json +37 -0
- package/src/schema/generated/polymax.market-ref.json +25 -0
- package/src/schema/generated/polymax.performance.json +65 -0
- package/src/schema/generated/polymax.profile.json +16 -0
- package/src/schema/generated/polymax.scan-result.json +50 -0
- package/src/schema/generated/polymax.status.json +40 -0
- package/src/schema/generated/polymax.tags.json +53 -0
- package/src/schema/generated/polymax.trader.json +16 -0
- package/src/schema/generated/polymax.wallet-market.json +50 -0
- package/src/schema/generated/polymax.wallet-pnl.json +35 -0
- package/src/schema/generated/pult.concept.json +53 -0
- package/src/schema/generated/pult.config.json +227 -0
- package/src/schema/generated/pult.connector.json +72 -0
- package/src/schema/generated/pult.market.json +113 -0
- package/src/schema/generated/pult.order.json +113 -0
- package/src/schema/generated/pult.rete.json +68 -0
- package/src/schema/generated/pult.sensor.json +74 -0
- package/src/schema/generated/pult.signal.json +54 -0
- package/src/schema/generated/pult.synapse.json +93 -0
- package/src/schema/generated/pult.trade.json +93 -0
- package/src/schema/generated/resim.config.json +34 -0
- package/src/schema/generated/resim.function.json +62 -0
- package/src/schema/generated/resim.goal.json +22 -0
- package/src/schema/generated/resim.resource.json +40 -0
- package/src/schema/generated/resim.state.json +48 -0
- package/src/schema/generated/resim.world.json +40 -0
- package/src/schema/generated/saveme.action.save.json +29 -0
- package/src/schema/generated/saveme.message.json +36 -0
- package/src/schema/generated/saveme.router.json +31 -0
- package/src/schema/generated/t.coolify.json +50 -0
- package/src/schema/generated/t.event.json +46 -0
- package/src/schema/generated/t.logs.json +155 -0
- package/src/schema/generated/t.note.json +31 -0
- package/src/schema/generated/t.person.json +36 -0
- package/src/schema/generated/t.tenant.json +57 -0
- package/src/schema/generated/t.tenant.status.json +42 -0
- package/src/schema/generated/tagger.config.json +115 -0
- package/src/schema/generated/tagger.result.json +57 -0
- package/src/schema/generated/tagger.tree.json +36 -0
- package/src/schema/generated/ui.table.json +46 -0
- package/src/schema/types.ts +1 -0
- package/src/server/actions.test.ts +1 -1
- package/src/server/actions.ts +1 -1
- package/src/server/api.test.ts +9 -0
- package/src/server/auth.ts +4 -3
- package/src/server/client.ts +1 -1
- package/src/server/coverage.test.ts +1 -1
- package/src/server/doc-index.ts +13 -12
- package/src/server/e2e.test.ts +4 -3
- package/src/server/factory.ts +46 -24
- package/src/server/main.ts +4 -36
- package/src/server/migrate.ts +4 -4
- package/src/server/mods-mount.ts +0 -2
- package/src/server/mount-adapters.ts +9 -4
- package/src/server/mount.test.ts +73 -5
- package/src/server/prefab.ts +3 -2
- package/src/server/refs.test.ts +82 -0
- package/src/server/refs.ts +64 -0
- package/src/server/server.ts +14 -3
- package/src/server/sub.ts +2 -2
- package/src/server/trpc.ts +9 -3
- package/src/tree/fs.ts +21 -15
- package/src/tree/index.test.ts +26 -0
- package/src/tree/index.ts +2 -1
- package/src/tree-chain.test.ts +37 -44
- package/src/tree-chain.ts +11 -5
- package/src/uri.test.ts +32 -5
- package/src/uri.ts +4 -2
- package/dist/mods/mcp/server.d.ts.map +0 -1
- package/dist/mods/mcp/server.js.map +0 -1
- package/dist/mods/mcp/service.d.ts.map +0 -1
- package/dist/mods/mcp/service.js.map +0 -1
- package/dist/mods/mcp/types.d.ts.map +0 -1
- package/dist/mods/mcp/types.js.map +0 -1
- package/dist/schema/test-opaque.d.ts +0 -3
- package/dist/schema/test-opaque.d.ts.map +0 -1
- package/dist/schema/test-opaque.js +0 -43
- package/dist/schema/test-opaque.js.map +0 -1
- package/dist/server/mcp.d.ts.map +0 -1
- package/dist/server/mcp.js.map +0 -1
- package/src/mods/mcp/CLAUDE.md +0 -6
- package/src/mods/mcp/server.ts +0 -2
- package/src/mods/mcp/service.ts +0 -19
- package/src/mods/mcp/types.ts +0 -7
- package/src/schema/test-opaque.ts +0 -42
- package/src/server/mcp.ts +0 -326
package/src/server/server.ts
CHANGED
|
@@ -14,9 +14,13 @@ import { withMounts } from './mount';
|
|
|
14
14
|
import type { ReactiveTree } from './sub';
|
|
15
15
|
import { unwatchAllQueries, withSubscriptions } from './sub';
|
|
16
16
|
import { createTreeRouter, type TreeRouter, type TrpcContext } from './trpc';
|
|
17
|
+
import { withRefIndex } from './refs';
|
|
17
18
|
import { withValidation } from './validate';
|
|
18
19
|
import { withVolatile } from './volatile';
|
|
19
20
|
import { createWatchManager, type WatchManager } from './watch';
|
|
21
|
+
import { createLogger } from '#log';
|
|
22
|
+
|
|
23
|
+
const log = createLogger('http');
|
|
20
24
|
|
|
21
25
|
export type RouteHandler = (req: import('node:http').IncomingMessage, res: import('node:http').ServerResponse, store: Tree) => Promise<void>;
|
|
22
26
|
|
|
@@ -36,7 +40,8 @@ export function createPipeline(bootstrap: Tree): Pipeline {
|
|
|
36
40
|
const mountable = withMounts(bootstrap);
|
|
37
41
|
const volatile = withVolatile(mountable);
|
|
38
42
|
const validated = withValidation(volatile);
|
|
39
|
-
const
|
|
43
|
+
const refsIndexed = withRefIndex(validated);
|
|
44
|
+
const cached = withCache(refsIndexed);
|
|
40
45
|
const watcher = createWatchManager({
|
|
41
46
|
onUserRemoved: (userId) => unwatchAllQueries(userId),
|
|
42
47
|
});
|
|
@@ -130,7 +135,10 @@ export function createHttpServer(pipeline: Pipeline, opts?: HttpServerOpts): Ser
|
|
|
130
135
|
// tRPC routes
|
|
131
136
|
if (pathname.startsWith('/trpc')) {
|
|
132
137
|
const path = pathname.replace(/^\/trpc/, '').replace(/^\//, '');
|
|
133
|
-
await nodeHTTPRequestHandler({
|
|
138
|
+
await nodeHTTPRequestHandler({
|
|
139
|
+
req, res, router, path, createContext,
|
|
140
|
+
onError: ({ error, path: p }) => log.error(`trpc ${p}: ${error.message}`),
|
|
141
|
+
});
|
|
134
142
|
return;
|
|
135
143
|
}
|
|
136
144
|
|
|
@@ -139,7 +147,10 @@ export function createHttpServer(pipeline: Pipeline, opts?: HttpServerOpts): Ser
|
|
|
139
147
|
|
|
140
148
|
// Fallback: try tRPC for legacy non-prefixed calls
|
|
141
149
|
const path = pathname.replace(/^\//, '');
|
|
142
|
-
await nodeHTTPRequestHandler({
|
|
150
|
+
await nodeHTTPRequestHandler({
|
|
151
|
+
req, res, router, path, createContext,
|
|
152
|
+
onError: ({ error, path: p }) => log.error(`trpc ${p}: ${error.message}`),
|
|
153
|
+
});
|
|
143
154
|
});
|
|
144
155
|
}
|
|
145
156
|
|
package/src/server/sub.ts
CHANGED
|
@@ -26,7 +26,7 @@ export type NodeEvent =
|
|
|
26
26
|
| { type: 'reconnect'; preserved: boolean };
|
|
27
27
|
|
|
28
28
|
// Strip empty arrays and $path from node to keep wire format clean
|
|
29
|
-
function cleanEvent(event:
|
|
29
|
+
function cleanEvent<T extends NodeEvent>(event: T): T {
|
|
30
30
|
const e = { ...event };
|
|
31
31
|
if ('addVps' in e && e.addVps && e.addVps.length === 0) delete e.addVps;
|
|
32
32
|
if ('rmVps' in e && e.rmVps && e.rmVps.length === 0) delete e.rmVps;
|
|
@@ -90,7 +90,7 @@ export function withSubscriptions(
|
|
|
90
90
|
type DataEvent = Exclude<NodeEvent, { type: 'reconnect' }>;
|
|
91
91
|
|
|
92
92
|
function emit(raw: DataEvent) {
|
|
93
|
-
const event = cleanEvent(raw)
|
|
93
|
+
const event = cleanEvent(raw);
|
|
94
94
|
|
|
95
95
|
const exact = exactListeners.get(event.path);
|
|
96
96
|
if (exact) for (const fn of exact) fn(event);
|
package/src/server/trpc.ts
CHANGED
|
@@ -66,6 +66,7 @@ export function createTreeRouter(baseStore: ReactiveTree, watcher: WatchManager)
|
|
|
66
66
|
// Session-level claims (agents) override dynamic buildClaims (users)
|
|
67
67
|
const claims = ctx.session?.claims ?? (userId ? await buildClaims(baseStore, userId) : ['public']);
|
|
68
68
|
const store = withAcl(baseStore, userId, claims);
|
|
69
|
+
|
|
69
70
|
const result = await next({ ctx: { ...ctx, store } });
|
|
70
71
|
|
|
71
72
|
if (!result.ok) {
|
|
@@ -214,10 +215,11 @@ export function createTreeRouter(baseStore: ReactiveTree, watcher: WatchManager)
|
|
|
214
215
|
const userPath = `/auth/users/${input.userId}`;
|
|
215
216
|
const user = await baseStore.get(userPath);
|
|
216
217
|
const cv = user ? user['credentials'] : undefined;
|
|
217
|
-
const creds = isComponent(cv) ? cv
|
|
218
|
+
const creds = isComponent(cv) ? cv : undefined;
|
|
218
219
|
// Always run scrypt to prevent timing-based user enumeration
|
|
219
|
-
const
|
|
220
|
-
|
|
220
|
+
const hash = typeof creds?.['hash'] === 'string' ? creds['hash'] : undefined;
|
|
221
|
+
const ok = await verifyPassword(input.password, hash ?? DUMMY_HASH);
|
|
222
|
+
if (!user || !hash || !ok) throw new TRPCError({ code: 'UNAUTHORIZED', message: 'Invalid credentials' });
|
|
221
223
|
const token = await createSession(baseStore, input.userId);
|
|
222
224
|
return { token, userId: input.userId };
|
|
223
225
|
}),
|
|
@@ -227,6 +229,10 @@ export function createTreeRouter(baseStore: ReactiveTree, watcher: WatchManager)
|
|
|
227
229
|
return { userId: ctx.session.userId };
|
|
228
230
|
}),
|
|
229
231
|
|
|
232
|
+
getPerm: authed
|
|
233
|
+
.input(z.object({ path: z.string() }))
|
|
234
|
+
.query(async ({ input, ctx }) => ctx.store.getPerm(input.path)),
|
|
235
|
+
|
|
230
236
|
logout: authed.mutation(async ({ ctx }) => {
|
|
231
237
|
if (!ctx.session || !ctx.token) return { ok: false };
|
|
232
238
|
await revokeSession(baseStore, ctx.token);
|
package/src/tree/fs.ts
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
// Auto-promotes leaf→dir when children appear, demotes dir→leaf when last child removed.
|
|
5
5
|
|
|
6
6
|
import type { NodeData } from '#core';
|
|
7
|
-
import { dirname as treeDirname
|
|
7
|
+
import { dirname as treeDirname } from '#core/path';
|
|
8
8
|
import { mkdir, readdir, readFile, rmdir, unlink, writeFile } from 'node:fs/promises';
|
|
9
9
|
import { dirname, join, resolve } from 'node:path';
|
|
10
10
|
import sift from 'sift';
|
|
@@ -128,10 +128,12 @@ export async function createFsTree(rootDir: string): Promise<Tree> {
|
|
|
128
128
|
}
|
|
129
129
|
}
|
|
130
130
|
|
|
131
|
-
//
|
|
132
|
-
async function
|
|
131
|
+
// Collect children of a tree path up to given depth by walking only the relevant FS subtree
|
|
132
|
+
async function collectChildren(parent: string, depth: number): Promise<NodeData[]> {
|
|
133
133
|
const results: NodeData[] = [];
|
|
134
|
-
|
|
134
|
+
const fsDir = resolve(join(rootDir, parent));
|
|
135
|
+
|
|
136
|
+
async function walk(dir: string, currentDepth: number) {
|
|
135
137
|
let entries;
|
|
136
138
|
try { entries = await readdir(dir, { withFileTypes: true }); } catch (e: any) {
|
|
137
139
|
if (e.code === 'ENOENT') return;
|
|
@@ -139,14 +141,24 @@ export async function createFsTree(rootDir: string): Promise<Tree> {
|
|
|
139
141
|
}
|
|
140
142
|
|
|
141
143
|
for (const e of entries) {
|
|
144
|
+
if (e.name === '$.json') continue; // parent's own data, not a child
|
|
142
145
|
const full = join(dir, e.name);
|
|
143
|
-
|
|
144
|
-
if (e.
|
|
145
|
-
|
|
146
|
+
|
|
147
|
+
if (e.isDirectory()) {
|
|
148
|
+
// Directory child — read its $.json if exists
|
|
149
|
+
const childPath = full.slice(rootDir.length) || '/';
|
|
150
|
+
const node = await readNode(childPath);
|
|
151
|
+
if (node) results.push(node);
|
|
152
|
+
if (currentDepth < depth) await walk(full, currentDepth + 1);
|
|
153
|
+
} else if (e.name.endsWith('.json')) {
|
|
154
|
+
// Leaf child — name.json
|
|
155
|
+
const node: NodeData = JSON.parse(await readFile(full, 'utf-8'));
|
|
156
|
+
results.push(node);
|
|
146
157
|
}
|
|
147
158
|
}
|
|
148
159
|
}
|
|
149
|
-
|
|
160
|
+
|
|
161
|
+
await walk(fsDir, 1);
|
|
150
162
|
return results;
|
|
151
163
|
}
|
|
152
164
|
|
|
@@ -157,13 +169,7 @@ export async function createFsTree(rootDir: string): Promise<Tree> {
|
|
|
157
169
|
|
|
158
170
|
async getChildren(parent, opts) {
|
|
159
171
|
const depth = opts?.depth ?? 1;
|
|
160
|
-
|
|
161
|
-
let filtered = all.filter((n) => {
|
|
162
|
-
if (!isChildPath(parent, n.$path, false)) return false;
|
|
163
|
-
if (depth === Infinity) return true;
|
|
164
|
-
const rest = parent === '/' ? n.$path.slice(1) : n.$path.slice(parent.length + 1);
|
|
165
|
-
return rest.split('/').length <= depth;
|
|
166
|
-
});
|
|
172
|
+
let filtered = await collectChildren(parent, depth);
|
|
167
173
|
if (opts?.query) {
|
|
168
174
|
const test = sift(opts.query);
|
|
169
175
|
filtered = filtered.filter(n => test(mapNodeForSift(n)));
|
package/src/tree/index.test.ts
CHANGED
|
@@ -106,6 +106,32 @@ describe('MemoryStore', () => {
|
|
|
106
106
|
assert.deepEqual(result.items, all.items.slice(1, 3));
|
|
107
107
|
});
|
|
108
108
|
|
|
109
|
+
it('get returns isolated copy — mutating result does not affect stored node', async () => {
|
|
110
|
+
const store = createMemoryTree();
|
|
111
|
+
await store.set(createNode('/x', 'item', { tags: ['a', 'b'] }));
|
|
112
|
+
|
|
113
|
+
const copy = await store.get('/x') as any;
|
|
114
|
+
copy.tags.push('mutated');
|
|
115
|
+
copy.extra = 'injected';
|
|
116
|
+
|
|
117
|
+
const stored = await store.get('/x') as any;
|
|
118
|
+
assert.deepEqual(stored.tags, ['a', 'b']);
|
|
119
|
+
assert.equal(stored.extra, undefined);
|
|
120
|
+
});
|
|
121
|
+
|
|
122
|
+
it('set stores isolated copy — mutating original after set does not affect stored node', async () => {
|
|
123
|
+
const store = createMemoryTree();
|
|
124
|
+
const node = createNode('/y', 'item', { value: 1 }) as any;
|
|
125
|
+
await store.set(node);
|
|
126
|
+
|
|
127
|
+
node.value = 999;
|
|
128
|
+
node.injected = true;
|
|
129
|
+
|
|
130
|
+
const stored = await store.get('/y') as any;
|
|
131
|
+
assert.equal(stored.value, 1);
|
|
132
|
+
assert.equal(stored.injected, undefined);
|
|
133
|
+
});
|
|
134
|
+
|
|
109
135
|
});
|
|
110
136
|
|
|
111
137
|
describe('OverlayStore', () => {
|
package/src/tree/index.ts
CHANGED
|
@@ -165,7 +165,8 @@ export function createMemoryTree(): Tree {
|
|
|
165
165
|
return {
|
|
166
166
|
async get(path, _ctx) {
|
|
167
167
|
if (typeof path !== 'string') throw new Error(`store.get: path must be string, got ${typeof path}`);
|
|
168
|
-
|
|
168
|
+
const data = navigate(path)?.data;
|
|
169
|
+
return data ? structuredClone(data) : data;
|
|
169
170
|
},
|
|
170
171
|
|
|
171
172
|
async getChildren(parent, opts, _ctx) {
|
package/src/tree-chain.test.ts
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import
|
|
7
|
-
import {
|
|
8
|
-
import
|
|
1
|
+
import { refVal, type TypedRef } from '#chain';
|
|
2
|
+
import { registerType } from '#comp';
|
|
3
|
+
import { isRef } from '#core';
|
|
4
|
+
import type { Tree } from '#tree';
|
|
5
|
+
import { createMemoryTree } from '#tree';
|
|
6
|
+
import assert from 'node:assert/strict';
|
|
7
|
+
import { describe, test } from 'node:test';
|
|
8
|
+
import { treeChain } from './tree-chain';
|
|
9
9
|
|
|
10
10
|
// ── Test types ──
|
|
11
11
|
|
|
@@ -14,12 +14,17 @@ class Scanner {
|
|
|
14
14
|
intervalMs = 900_000
|
|
15
15
|
maxRetries = 3
|
|
16
16
|
livePrices: TypedRef<LivePrices> = refVal(LivePrices)
|
|
17
|
+
scan() { return { started: true } }
|
|
18
|
+
configure(data: { interval: number }) { return data }
|
|
17
19
|
}
|
|
18
20
|
registerType('tch.scanner', Scanner)
|
|
19
21
|
|
|
20
22
|
class LivePrices {
|
|
21
23
|
static $type = 'tch.live-prices'
|
|
22
24
|
feederUrl = 'ws://localhost:8090'
|
|
25
|
+
subscribe(data: { slugs: string[] }) {
|
|
26
|
+
return data.slugs.map((s: string) => ({ slug: s, bid: 0.6 }))
|
|
27
|
+
}
|
|
23
28
|
}
|
|
24
29
|
registerType('tch.live-prices', LivePrices)
|
|
25
30
|
|
|
@@ -37,14 +42,6 @@ class Wallet {
|
|
|
37
42
|
}
|
|
38
43
|
registerType('tch.wallet', Wallet)
|
|
39
44
|
|
|
40
|
-
// ── Register actions ──
|
|
41
|
-
|
|
42
|
-
register('tch.scanner', 'action:scan', () => ({ started: true }))
|
|
43
|
-
register('tch.scanner', 'action:configure', (_ctx: any, data: any) => data)
|
|
44
|
-
register('tch.live-prices', 'action:subscribe', (_ctx: any, data: any) =>
|
|
45
|
-
data.slugs.map((s: string) => ({ slug: s, bid: 0.6 })),
|
|
46
|
-
)
|
|
47
|
-
|
|
48
45
|
// ── Seed ──
|
|
49
46
|
|
|
50
47
|
async function seed(): Promise<Tree> {
|
|
@@ -80,8 +77,6 @@ async function seed(): Promise<Tree> {
|
|
|
80
77
|
return tree
|
|
81
78
|
}
|
|
82
79
|
|
|
83
|
-
import { treeChain } from './tree-chain'
|
|
84
|
-
|
|
85
80
|
describe('treeChain — path building', () => {
|
|
86
81
|
test('$path from dot navigation', () => {
|
|
87
82
|
const c = treeChain(null as any)
|
|
@@ -133,9 +128,9 @@ describe('treeChain — $get (typed component)', () => {
|
|
|
133
128
|
assert.equal(scanner.maxRetries, 3)
|
|
134
129
|
})
|
|
135
130
|
|
|
136
|
-
test('$
|
|
131
|
+
test('$field with named component', async () => {
|
|
137
132
|
const tree = await seed()
|
|
138
|
-
const wallet = await treeChain(tree).users.alice.$
|
|
133
|
+
const wallet = await treeChain(tree).users.alice.$field('wallet')
|
|
139
134
|
assert.equal(wallet.address, '0xabc')
|
|
140
135
|
})
|
|
141
136
|
|
|
@@ -290,6 +285,8 @@ class BoardTask {
|
|
|
290
285
|
title = ''
|
|
291
286
|
status = 'backlog'
|
|
292
287
|
priority = 'normal'
|
|
288
|
+
move(data: { status: string }) { return { moved: data.status } }
|
|
289
|
+
assign(data: { to: string }) { return { assigned: data.to } }
|
|
293
290
|
}
|
|
294
291
|
registerType('tch.board.task', BoardTask)
|
|
295
292
|
|
|
@@ -316,13 +313,10 @@ class BrahmanBot {
|
|
|
316
313
|
static $type = 'tch.brahman.bot'
|
|
317
314
|
alias = ''
|
|
318
315
|
running = false
|
|
316
|
+
restart() { return { restarted: true } }
|
|
319
317
|
}
|
|
320
318
|
registerType('tch.brahman.bot', BrahmanBot)
|
|
321
319
|
|
|
322
|
-
register('tch.board.task', 'action:move', (_ctx: any, data: any) => ({ moved: data.status }))
|
|
323
|
-
register('tch.board.task', 'action:assign', (_ctx: any, data: any) => ({ assigned: data.to }))
|
|
324
|
-
register('tch.brahman.bot', 'action:restart', () => ({ restarted: true }))
|
|
325
|
-
|
|
326
320
|
async function seedRealWorld(): Promise<Tree> {
|
|
327
321
|
const tree = createMemoryTree()
|
|
328
322
|
|
|
@@ -557,22 +551,17 @@ describe('treeChain — $set', () => {
|
|
|
557
551
|
})
|
|
558
552
|
|
|
559
553
|
describe('treeChain — Symbol traps', () => {
|
|
560
|
-
test('Symbol.toPrimitive returns TreeChain(path)', () => {
|
|
561
|
-
const c = treeChain(null as any)
|
|
562
|
-
assert.equal(c.services.scanner[Symbol.toPrimitive], 'TreeChain(/services/scanner)')
|
|
563
|
-
})
|
|
564
|
-
|
|
565
554
|
test('Symbol.toPrimitive on root', () => {
|
|
566
|
-
assert.equal(treeChain(null as any)[Symbol.toPrimitive], 'TreeChain(/)')
|
|
555
|
+
assert.equal((treeChain(null as any) as any)[Symbol.toPrimitive], 'TreeChain(/)')
|
|
567
556
|
})
|
|
568
557
|
|
|
569
558
|
test('Symbol.toStringTag', () => {
|
|
570
|
-
const c = treeChain(null as any)
|
|
571
|
-
assert.equal(c[Symbol.toStringTag], 'TreeChain(/foo)')
|
|
559
|
+
const c = treeChain(null as any) as any
|
|
560
|
+
assert.equal(c.foo[Symbol.toStringTag], 'TreeChain(/foo)')
|
|
572
561
|
})
|
|
573
562
|
|
|
574
563
|
test('other symbols return undefined', () => {
|
|
575
|
-
const c = treeChain(null as any)
|
|
564
|
+
const c = treeChain(null as any) as any
|
|
576
565
|
assert.equal(c[Symbol.iterator], undefined)
|
|
577
566
|
assert.equal(c[Symbol.asyncIterator], undefined)
|
|
578
567
|
})
|
|
@@ -601,32 +590,35 @@ describe('treeChain — basePath edge cases', () => {
|
|
|
601
590
|
describe('treeChain — error paths', () => {
|
|
602
591
|
test('action without (Class) throws', async () => {
|
|
603
592
|
const tree = await seed()
|
|
593
|
+
const t = treeChain(tree) as any
|
|
604
594
|
await assert.rejects(
|
|
605
|
-
async () => { await
|
|
595
|
+
async () => { await t.services.scanner.scan() },
|
|
606
596
|
(e: Error) => e.message.includes('Class'),
|
|
607
597
|
)
|
|
608
598
|
})
|
|
609
599
|
|
|
610
600
|
test('unregistered action throws', async () => {
|
|
611
601
|
const tree = await seed()
|
|
602
|
+
const t = treeChain(tree) as any
|
|
612
603
|
await assert.rejects(
|
|
613
|
-
async () => { await
|
|
604
|
+
async () => { await t.services.scanner(Scanner).nonexistent() },
|
|
614
605
|
(e: Error) => e.message.includes('action'),
|
|
615
606
|
)
|
|
616
607
|
})
|
|
617
608
|
|
|
618
609
|
test('null field in ops throws', async () => {
|
|
619
610
|
const tree = await seed()
|
|
611
|
+
const t = treeChain(tree) as any
|
|
620
612
|
await assert.rejects(
|
|
621
|
-
async () => { await
|
|
613
|
+
async () => { await t.services.scanner.$get(Scanner).noSuchField },
|
|
622
614
|
(e: Error) => e.message.includes('null'),
|
|
623
615
|
)
|
|
624
616
|
})
|
|
625
617
|
|
|
626
|
-
test('$
|
|
618
|
+
test('$field with missing named component throws', async () => {
|
|
627
619
|
const tree = await seed()
|
|
628
620
|
await assert.rejects(
|
|
629
|
-
async () => { await treeChain(tree).services.scanner.$
|
|
621
|
+
async () => { await treeChain(tree).services.scanner.$field('ghost') },
|
|
630
622
|
(e: Error) => e.message.includes('ghost'),
|
|
631
623
|
)
|
|
632
624
|
})
|
|
@@ -638,14 +630,15 @@ describe('treeChain — error paths', () => {
|
|
|
638
630
|
})
|
|
639
631
|
|
|
640
632
|
describe('treeChain — (Class) where node.$type matches', () => {
|
|
641
|
-
test('
|
|
633
|
+
test('getComponent returns node itself when $type matches', async () => {
|
|
642
634
|
const tree = await seed()
|
|
643
635
|
// scanner.$type === 'tch.scanner', Scanner.$type === 'tch.scanner'
|
|
644
|
-
//
|
|
636
|
+
// getComponent returns node itself — all fields at node level
|
|
637
|
+
const node = await treeChain(tree).services.scanner
|
|
638
|
+
assert.equal(node.$type, 'tch.scanner')
|
|
639
|
+
assert.equal(node.$path, '/services/scanner')
|
|
645
640
|
const scanner = await treeChain(tree).services.scanner(Scanner)
|
|
646
|
-
assert.equal(scanner.$type, 'tch.scanner')
|
|
647
641
|
assert.equal(scanner.intervalMs, 900_000)
|
|
648
|
-
assert.equal(scanner.$path, '/services/scanner')
|
|
649
642
|
})
|
|
650
643
|
})
|
|
651
644
|
|
|
@@ -690,7 +683,7 @@ describe('treeChain — multiple ops chain', () => {
|
|
|
690
683
|
await tree.set({ $path: '/lp', $type: 'tch.live-prices', feederUrl: 'ws://chain' })
|
|
691
684
|
|
|
692
685
|
// $get → field (nested component, not a ref) → field
|
|
693
|
-
const chain = await treeChain(tree).config.$
|
|
686
|
+
const chain = await treeChain(tree).config.$field('nested').chain
|
|
694
687
|
assert.equal(chain, 'polygon')
|
|
695
688
|
})
|
|
696
689
|
})
|
|
@@ -700,7 +693,7 @@ describe('treeChain — chain isolation', () => {
|
|
|
700
693
|
const tree = await seed()
|
|
701
694
|
const t = treeChain(tree)
|
|
702
695
|
|
|
703
|
-
const chain1 = t.services.scanner
|
|
696
|
+
const chain1 = t.services.scanner
|
|
704
697
|
const chain2 = t.services['live-prices']
|
|
705
698
|
|
|
706
699
|
const s = await chain1
|
package/src/tree-chain.ts
CHANGED
|
@@ -2,10 +2,10 @@
|
|
|
2
2
|
// Navigate tree via dots, auto-follow refs, execute actions, typed components.
|
|
3
3
|
// Layer L2: uses Tree (L1) + comp (L2). No server dependency.
|
|
4
4
|
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import type { Tree } from '#tree'
|
|
8
|
-
import type { Chain } from './chain'
|
|
5
|
+
import { type Class, type Raw, type TypeClass } from '#comp';
|
|
6
|
+
import { getComponent, isComponent, isRef, type NodeData, normalizeType, resolve } from '#core';
|
|
7
|
+
import type { Tree } from '#tree';
|
|
8
|
+
import type { Chain } from './chain';
|
|
9
9
|
|
|
10
10
|
type Spec = { cls: Class | null; key?: string }
|
|
11
11
|
type Op = string | [string, unknown[]]
|
|
@@ -19,6 +19,7 @@ type TreeChainAPI = {
|
|
|
19
19
|
<T>(cls: TypeClass<T>): Chain<T>
|
|
20
20
|
readonly $path: string
|
|
21
21
|
$get<T>(cls: Class<T>, key?: string): Chain<T>
|
|
22
|
+
$field(key: string): Chain<any>
|
|
22
23
|
$children(query?: Record<string, unknown>): Promise<NodeData[]>
|
|
23
24
|
$set<T>(cls: Class<T>, data?: Partial<Raw<T>>): Promise<void>
|
|
24
25
|
then<R1 = NodeData, R2 = never>(
|
|
@@ -47,7 +48,7 @@ async function exec(tree: Tree, path: string, spec: Spec | null, ops: Op[]): Pro
|
|
|
47
48
|
cur = ck
|
|
48
49
|
curType = cur.$type
|
|
49
50
|
} else if (spec.cls) {
|
|
50
|
-
const comp =
|
|
51
|
+
const comp = getComponent(node, spec.cls)
|
|
51
52
|
if (!comp) throw new Error(`Type "${normalizeType(spec.cls)}" not found on ${path}`)
|
|
52
53
|
cur = comp
|
|
53
54
|
curType = comp.$type ?? curType
|
|
@@ -97,6 +98,11 @@ function make(tree: Tree, path: string, spec: Spec | null, ops: Op[]): any {
|
|
|
97
98
|
make(tree, path, { cls, key }, NO_OPS)
|
|
98
99
|
}
|
|
99
100
|
|
|
101
|
+
if (p === '$field') {
|
|
102
|
+
return (key: string) =>
|
|
103
|
+
make(tree, path, { cls: null, key }, NO_OPS)
|
|
104
|
+
}
|
|
105
|
+
|
|
100
106
|
if (p === '$children') {
|
|
101
107
|
return (query?: Record<string, unknown>) =>
|
|
102
108
|
tree.getChildren(path, query ? { query } : undefined).then(r => r.items)
|
package/src/uri.test.ts
CHANGED
|
@@ -3,22 +3,22 @@ import { describe, it } from 'node:test';
|
|
|
3
3
|
import { parseURI } from './uri';
|
|
4
4
|
|
|
5
5
|
describe('parseURI', () => {
|
|
6
|
-
it('
|
|
6
|
+
it('#name = key (component/field access)', () => {
|
|
7
7
|
const r = parseURI('/sys/types/cafe/contact#schema')
|
|
8
|
-
assert.deepEqual(r, { path: '/sys/types/cafe/contact',
|
|
8
|
+
assert.deepEqual(r, { path: '/sys/types/cafe/contact', key: 'schema' })
|
|
9
9
|
})
|
|
10
10
|
|
|
11
|
-
it('
|
|
11
|
+
it('#key.field = sub-field within component', () => {
|
|
12
12
|
const r = parseURI('/users/me#profile.email')
|
|
13
13
|
assert.deepEqual(r, { path: '/users/me', key: 'profile', field: 'email' })
|
|
14
14
|
})
|
|
15
15
|
|
|
16
|
-
it('action
|
|
16
|
+
it('#action() = node-level action (no key)', () => {
|
|
17
17
|
const r = parseURI('/cafe/contact#submit()')
|
|
18
18
|
assert.deepEqual(r, { path: '/cafe/contact', action: 'submit' })
|
|
19
19
|
})
|
|
20
20
|
|
|
21
|
-
it('action on named component', () => {
|
|
21
|
+
it('#key.action() = action on named component', () => {
|
|
22
22
|
const r = parseURI('/cafe/contact#contact.submit()')
|
|
23
23
|
assert.deepEqual(r, { path: '/cafe/contact', key: 'contact', action: 'submit' })
|
|
24
24
|
})
|
|
@@ -83,4 +83,31 @@ describe('parseURI', () => {
|
|
|
83
83
|
const r = parseURI('/x#submit()')
|
|
84
84
|
assert.equal(r.data, undefined)
|
|
85
85
|
})
|
|
86
|
+
|
|
87
|
+
it('#key does not set field or action', () => {
|
|
88
|
+
const r = parseURI('/x#view')
|
|
89
|
+
assert.equal(r.key, 'view')
|
|
90
|
+
assert.equal(r.field, undefined)
|
|
91
|
+
assert.equal(r.action, undefined)
|
|
92
|
+
})
|
|
93
|
+
|
|
94
|
+
it('#key.field does not set action', () => {
|
|
95
|
+
const r = parseURI('/x#profile.name')
|
|
96
|
+
assert.equal(r.key, 'profile')
|
|
97
|
+
assert.equal(r.field, 'name')
|
|
98
|
+
assert.equal(r.action, undefined)
|
|
99
|
+
})
|
|
100
|
+
|
|
101
|
+
it('#action() does not set key', () => {
|
|
102
|
+
const r = parseURI('/x#run()')
|
|
103
|
+
assert.equal(r.action, 'run')
|
|
104
|
+
assert.equal(r.key, undefined)
|
|
105
|
+
})
|
|
106
|
+
|
|
107
|
+
it('#key.action() sets both key and action', () => {
|
|
108
|
+
const r = parseURI('/x#comp.run()')
|
|
109
|
+
assert.equal(r.key, 'comp')
|
|
110
|
+
assert.equal(r.action, 'run')
|
|
111
|
+
assert.equal(r.field, undefined)
|
|
112
|
+
})
|
|
86
113
|
})
|
package/src/uri.ts
CHANGED
|
@@ -29,10 +29,12 @@ export function parseURI(uri: string): TreenityURI {
|
|
|
29
29
|
const dot = clean.indexOf('.')
|
|
30
30
|
const key = dot > -1 ? clean.slice(0, dot) : undefined
|
|
31
31
|
const name = dot > -1 ? clean.slice(dot + 1) : clean
|
|
32
|
-
if (!name) throw new Error('Empty name in URI fragment')
|
|
32
|
+
if (dot > -1 && !name) throw new Error('Empty name in URI fragment')
|
|
33
33
|
|
|
34
34
|
if (key) result.key = key
|
|
35
|
-
if (isCall) result.action = name
|
|
35
|
+
if (isCall) { result.action = name }
|
|
36
|
+
else if (key) { result.field = name }
|
|
37
|
+
else { result.key = name }
|
|
36
38
|
}
|
|
37
39
|
|
|
38
40
|
const data = url.search ? expandDots(url.searchParams) : undefined
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../../src/mods/mcp/server.ts"],"names":[],"mappings":"AAAA,OAAO,SAAS,CAAC;AACjB,OAAO,WAAW,CAAC"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"server.js","sourceRoot":"","sources":["../../../src/mods/mcp/server.ts"],"names":[],"mappings":"AAAA,OAAO,SAAS,CAAC;AACjB,OAAO,WAAW,CAAC"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"service.d.ts","sourceRoot":"","sources":["../../../src/mods/mcp/service.ts"],"names":[],"mappings":""}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"service.js","sourceRoot":"","sources":["../../../src/mods/mcp/service.ts"],"names":[],"mappings":"AAAA,8EAA8E;AAE9E,OAAO,EAAE,OAAO,EAAE,MAAM,OAAO,CAAC;AAChC,OAAO,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AACjC,OAAO,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAClD,OAAO,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAEpC,QAAQ,CAAC,YAAY,EAAE,SAAS,EAAE,KAAK,EAAE,IAAI,EAAE,GAAG,EAAE,EAAE;IACpD,MAAM,MAAM,GAAG,OAAO,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;IACxC,MAAM,IAAI,GAAG,MAAM,EAAE,IAAI,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,IAAI,CAAC,CAAC;IACpE,MAAM,MAAM,GAAG,mBAAmB,CAAC,GAAG,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;IAEpD,OAAO;QACL,IAAI,EAAE,KAAK,IAAI,EAAE;YACf,MAAM,CAAC,KAAK,EAAE,CAAC;YACf,OAAO,CAAC,GAAG,CAAC,kBAAkB,IAAI,EAAE,CAAC,CAAC;QACxC,CAAC;KACF,CAAC;AACJ,CAAC,CAAC,CAAC"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/mods/mcp/types.ts"],"names":[],"mappings":"AAEA,sEAAsE;AACtE,qBAAa,SAAS;IACpB,IAAI,SAAQ;CACb"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/mods/mcp/types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,OAAO,CAAC;AAErC,sEAAsE;AACtE,MAAM,OAAO,SAAS;IACpB,IAAI,GAAG,IAAI,CAAC;CACb;AACD,YAAY,CAAC,YAAY,EAAE,SAAS,CAAC,CAAC"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"test-opaque.d.ts","sourceRoot":"","sources":["../../src/schema/test-opaque.ts"],"names":[],"mappings":""}
|
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env tsx
|
|
2
|
-
// Quick test: does getAliasedSymbol resolve import to original @opaque decl?
|
|
3
|
-
import * as ts from 'typescript';
|
|
4
|
-
import * as path from 'node:path';
|
|
5
|
-
const tsconfigPath = path.resolve(import.meta.dirname, '../../../tsconfig.json');
|
|
6
|
-
const configFile = ts.readConfigFile(tsconfigPath, ts.sys.readFile);
|
|
7
|
-
const parsed = ts.parseJsonConfigFileContent(configFile.config, ts.sys, path.dirname(tsconfigPath));
|
|
8
|
-
const program = ts.createProgram(parsed.fileNames, parsed.options);
|
|
9
|
-
const checker = program.getTypeChecker();
|
|
10
|
-
for (const sf of program.getSourceFiles()) {
|
|
11
|
-
if (!sf.fileName.includes('brahman/types'))
|
|
12
|
-
continue;
|
|
13
|
-
ts.forEachChild(sf, (node) => {
|
|
14
|
-
if (!ts.isClassDeclaration(node) || !node.name)
|
|
15
|
-
return;
|
|
16
|
-
if (node.name.text !== 'MessageAction')
|
|
17
|
-
return;
|
|
18
|
-
for (const member of node.members) {
|
|
19
|
-
if (!ts.isMethodDeclaration(member) || !member.name || !ts.isIdentifier(member.name))
|
|
20
|
-
continue;
|
|
21
|
-
if (member.name.text !== 'run')
|
|
22
|
-
continue;
|
|
23
|
-
const param = member.parameters[0];
|
|
24
|
-
if (!param?.type || !ts.isTypeReferenceNode(param.type)) {
|
|
25
|
-
console.log('no type ref');
|
|
26
|
-
return;
|
|
27
|
-
}
|
|
28
|
-
let sym = checker.getSymbolAtLocation(param.type.typeName);
|
|
29
|
-
console.log('sym:', sym?.name, 'flags:', sym?.flags, 'isAlias:', !!(sym?.flags & ts.SymbolFlags.Alias));
|
|
30
|
-
if (sym?.flags & ts.SymbolFlags.Alias) {
|
|
31
|
-
sym = checker.getAliasedSymbol(sym);
|
|
32
|
-
console.log('aliased to:', sym?.name, 'decls:', sym?.declarations?.length);
|
|
33
|
-
const decl = sym?.declarations?.[0];
|
|
34
|
-
if (decl) {
|
|
35
|
-
console.log('decl kind:', ts.SyntaxKind[decl.kind], 'at', path.basename(decl.getSourceFile().fileName));
|
|
36
|
-
console.log('JSDoc tags:', ts.getJSDocTags(decl).map(t => t.tagName.text));
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
});
|
|
41
|
-
break;
|
|
42
|
-
}
|
|
43
|
-
//# sourceMappingURL=test-opaque.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"test-opaque.js","sourceRoot":"","sources":["../../src/schema/test-opaque.ts"],"names":[],"mappings":"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"}
|
package/dist/server/mcp.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"mcp.d.ts","sourceRoot":"","sources":["../../src/server/mcp.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,OAAO,CAAC;AAGlC,OAAO,EAAgB,KAAK,MAAM,EAAE,MAAM,WAAW,CAAC;AA+QtD,8EAA8E;AAC9E,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CA4CrE"}
|