@jongleberry/atel 0.0.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/README.md +168 -0
- package/dist/cli/append.d.mts +3 -0
- package/dist/cli/append.mjs +38 -0
- package/dist/cli/args.d.mts +14 -0
- package/dist/cli/args.mjs +49 -0
- package/dist/cli/context.d.mts +15 -0
- package/dist/cli/context.mjs +1 -0
- package/dist/cli/credentials.d.mts +6 -0
- package/dist/cli/credentials.mjs +45 -0
- package/dist/cli/env.d.mts +5 -0
- package/dist/cli/env.mjs +21 -0
- package/dist/cli/errors.d.mts +3 -0
- package/dist/cli/errors.mjs +3 -0
- package/dist/cli/get.d.mts +9 -0
- package/dist/cli/get.mjs +55 -0
- package/dist/cli/index.d.mts +18 -0
- package/dist/cli/index.mjs +69 -0
- package/dist/cli/output.d.mts +4 -0
- package/dist/cli/output.mjs +4 -0
- package/dist/cli/patch.d.mts +7 -0
- package/dist/cli/patch.mjs +57 -0
- package/dist/cli/usage.d.mts +1 -0
- package/dist/cli/usage.mjs +21 -0
- package/dist/client/append.d.mts +5 -0
- package/dist/client/append.mjs +18 -0
- package/dist/client/auth.d.mts +26 -0
- package/dist/client/auth.mjs +23 -0
- package/dist/client/credentials.d.mts +13 -0
- package/dist/client/credentials.mjs +19 -0
- package/dist/client/errors.d.mts +8 -0
- package/dist/client/errors.mjs +13 -0
- package/dist/client/http.d.mts +22 -0
- package/dist/client/http.mjs +66 -0
- package/dist/client/journal.d.mts +24 -0
- package/dist/client/journal.mjs +35 -0
- package/dist/client/journals.d.mts +18 -0
- package/dist/client/journals.mjs +28 -0
- package/dist/client/patch.d.mts +6 -0
- package/dist/client/patch.mjs +12 -0
- package/dist/client/stream.d.mts +30 -0
- package/dist/client/stream.mjs +90 -0
- package/dist/client/types.d.mts +65 -0
- package/dist/client/types.mjs +8 -0
- package/dist/format-error.d.mts +6 -0
- package/dist/format-error.mjs +15 -0
- package/dist/index.d.mts +20 -0
- package/dist/index.mjs +16 -0
- package/dist/mcp/dispatch.d.mts +3 -0
- package/dist/mcp/dispatch.mjs +16 -0
- package/dist/mcp/schemas.d.mts +2 -0
- package/dist/mcp/schemas.mjs +69 -0
- package/dist/mcp/server.d.mts +10 -0
- package/dist/mcp/server.mjs +35 -0
- package/dist/mcp/tool-append.d.mts +3 -0
- package/dist/mcp/tool-append.mjs +17 -0
- package/dist/mcp/tool-get.d.mts +13 -0
- package/dist/mcp/tool-get.mjs +30 -0
- package/dist/mcp/tool-patch.d.mts +5 -0
- package/dist/mcp/tool-patch.mjs +22 -0
- package/dist/mcp/validate.d.mts +6 -0
- package/dist/mcp/validate.mjs +28 -0
- package/dist/session.d.mts +24 -0
- package/dist/session.mjs +68 -0
- package/package.json +45 -0
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The three MCP tools this server exposes. Credential management
|
|
3
|
+
* (`create`/`list`/`delete`) is deliberately NOT here — that's CLI/admin
|
|
4
|
+
* only, per the plan's hard separation between admin and telemetry
|
|
5
|
+
* surfaces.
|
|
6
|
+
*/
|
|
7
|
+
const TELEMETRY_APPEND_TOOL = {
|
|
8
|
+
name: 'telemetry_append',
|
|
9
|
+
description: 'Append a telemetry entry for the current (or given) session. `data` is unstructured JSON — attach whatever is useful: notes, branch names, PR numbers, decisions made. This is a stream-of-consciousness log, not a knowledge base.',
|
|
10
|
+
inputSchema: {
|
|
11
|
+
type: 'object',
|
|
12
|
+
properties: {
|
|
13
|
+
data: { type: 'object', description: 'Unstructured JSON payload for this entry.' },
|
|
14
|
+
sessionId: {
|
|
15
|
+
type: 'string',
|
|
16
|
+
description: 'Session id to record telemetry under. Defaults to the current session.',
|
|
17
|
+
},
|
|
18
|
+
agent: { type: 'string', description: "Agent identifier. Defaults to 'claude-code'." },
|
|
19
|
+
},
|
|
20
|
+
required: ['data'],
|
|
21
|
+
},
|
|
22
|
+
};
|
|
23
|
+
const TELEMETRY_GET_TOOL = {
|
|
24
|
+
name: 'telemetry_get',
|
|
25
|
+
description: 'Reads back telemetry entries for the current (or given) session, optionally filtered by agent/archived.',
|
|
26
|
+
inputSchema: {
|
|
27
|
+
type: 'object',
|
|
28
|
+
properties: {
|
|
29
|
+
sessionId: {
|
|
30
|
+
type: 'string',
|
|
31
|
+
description: 'Session id to read. Defaults to the current session.',
|
|
32
|
+
},
|
|
33
|
+
agent: { type: 'string', description: 'Filter by agent identifier.' },
|
|
34
|
+
archived: { type: 'boolean', description: 'Filter by archived status.' },
|
|
35
|
+
format: {
|
|
36
|
+
type: 'string',
|
|
37
|
+
enum: ['json', 'jsonl'],
|
|
38
|
+
description: 'Internal wire format. Defaults to jsonl.',
|
|
39
|
+
},
|
|
40
|
+
},
|
|
41
|
+
},
|
|
42
|
+
};
|
|
43
|
+
const TELEMETRY_PATCH_TOOL = {
|
|
44
|
+
name: 'telemetry_patch',
|
|
45
|
+
description: 'Batch-patches telemetry entries by id — archive them and/or shallow-merge new data into their existing `data` blob (e.g. attach a PR number once it exists).',
|
|
46
|
+
inputSchema: {
|
|
47
|
+
type: 'object',
|
|
48
|
+
properties: {
|
|
49
|
+
patches: {
|
|
50
|
+
type: 'array',
|
|
51
|
+
items: {
|
|
52
|
+
type: 'object',
|
|
53
|
+
properties: {
|
|
54
|
+
id: { type: 'string' },
|
|
55
|
+
archived: { type: 'boolean' },
|
|
56
|
+
data: { type: 'object', description: 'Shallow-merged into the existing data blob.' },
|
|
57
|
+
},
|
|
58
|
+
required: ['id'],
|
|
59
|
+
},
|
|
60
|
+
},
|
|
61
|
+
},
|
|
62
|
+
required: ['patches'],
|
|
63
|
+
},
|
|
64
|
+
};
|
|
65
|
+
export const TELEMETRY_TOOLS = [
|
|
66
|
+
TELEMETRY_APPEND_TOOL,
|
|
67
|
+
TELEMETRY_GET_TOOL,
|
|
68
|
+
TELEMETRY_PATCH_TOOL,
|
|
69
|
+
];
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { Server } from '@modelcontextprotocol/sdk/server/index.js';
|
|
2
|
+
import type { ClientConfig } from '../client/types.mjs';
|
|
3
|
+
/**
|
|
4
|
+
* Builds the MCP server with the three telemetry tools registered, but does
|
|
5
|
+
* not connect a transport — kept separate so tests can drive it over an
|
|
6
|
+
* `InMemoryTransport` instead of real stdio.
|
|
7
|
+
*/
|
|
8
|
+
export declare function createMcpServer(config: ClientConfig): Server;
|
|
9
|
+
/** Starts the MCP stdio server — the `atel mcp` entrypoint. */
|
|
10
|
+
export declare function startMcpServer(config: ClientConfig): Promise<void>;
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { Server } from '@modelcontextprotocol/sdk/server/index.js';
|
|
2
|
+
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
|
|
3
|
+
import { CallToolRequestSchema, ListToolsRequestSchema } from '@modelcontextprotocol/sdk/types.js';
|
|
4
|
+
import { formatError } from '../format-error.mjs';
|
|
5
|
+
import { dispatchTool } from './dispatch.mjs';
|
|
6
|
+
import { TELEMETRY_TOOLS } from './schemas.mjs';
|
|
7
|
+
const SERVER_INFO = { name: 'atel', version: '0.0.0' };
|
|
8
|
+
/**
|
|
9
|
+
* Builds the MCP server with the three telemetry tools registered, but does
|
|
10
|
+
* not connect a transport — kept separate so tests can drive it over an
|
|
11
|
+
* `InMemoryTransport` instead of real stdio.
|
|
12
|
+
*/
|
|
13
|
+
export function createMcpServer(config) {
|
|
14
|
+
const server = new Server(SERVER_INFO, { capabilities: { tools: {} } });
|
|
15
|
+
server.setRequestHandler(ListToolsRequestSchema, async () => ({ tools: TELEMETRY_TOOLS }));
|
|
16
|
+
server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
17
|
+
try {
|
|
18
|
+
const result = await dispatchTool(request.params.name, request.params.arguments ?? {}, config);
|
|
19
|
+
return { content: [{ type: 'text', text: JSON.stringify(result) }] };
|
|
20
|
+
}
|
|
21
|
+
catch (err) {
|
|
22
|
+
return { content: [{ type: 'text', text: formatError(err) }], isError: true };
|
|
23
|
+
}
|
|
24
|
+
});
|
|
25
|
+
return server;
|
|
26
|
+
}
|
|
27
|
+
/* v8 ignore start -- real stdio transport; requires an actual MCP client process attached to
|
|
28
|
+
stdin/stdout, which vitest can't drive. `createMcpServer` above (the tested logic) is exercised
|
|
29
|
+
directly via InMemoryTransport in server.test.mts. */
|
|
30
|
+
/** Starts the MCP stdio server — the `atel mcp` entrypoint. */
|
|
31
|
+
export async function startMcpServer(config) {
|
|
32
|
+
const server = createMcpServer(config);
|
|
33
|
+
await server.connect(new StdioServerTransport());
|
|
34
|
+
}
|
|
35
|
+
/* v8 ignore stop */
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { Telemetry } from '../client/journal.mjs';
|
|
2
|
+
import { resolveSessionId } from '../session.mjs';
|
|
3
|
+
import { expectObject, optionalString } from './validate.mjs';
|
|
4
|
+
const DEFAULT_AGENT = 'claude-code';
|
|
5
|
+
/** `telemetry_append` — args `{ data, sessionId?, agent? }`. */
|
|
6
|
+
export async function handleTelemetryAppend(args, config) {
|
|
7
|
+
const data = expectObject(args.data, 'data');
|
|
8
|
+
const sessionId = resolveSessionId(optionalString(args.sessionId, 'sessionId'));
|
|
9
|
+
const agent = optionalString(args.agent, 'agent') ?? DEFAULT_AGENT;
|
|
10
|
+
const telemetry = new Telemetry({
|
|
11
|
+
baseUrl: config.baseUrl,
|
|
12
|
+
token: config.token,
|
|
13
|
+
sessionId,
|
|
14
|
+
agent,
|
|
15
|
+
});
|
|
16
|
+
return telemetry.append(data);
|
|
17
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { ClientConfig, TelemetryEntry } from '../client/types.mjs';
|
|
2
|
+
/**
|
|
3
|
+
* `telemetry_get` — args `{ sessionId?, agent?, archived?, format? }`.
|
|
4
|
+
* Defaults `sessionId` to the current session (same resolution as
|
|
5
|
+
* `telemetry_append`), so "read back what I just recorded" works with no
|
|
6
|
+
* arguments. Collects the async-iterable client read into a single
|
|
7
|
+
* response, since MCP tool results aren't naturally streaming to the
|
|
8
|
+
* model — the underlying read still streams internally (see
|
|
9
|
+
* `client/stream.mts`), for consistency/reuse with the CLI and library.
|
|
10
|
+
*/
|
|
11
|
+
export declare function handleTelemetryGet(args: Record<string, unknown>, config: ClientConfig): Promise<{
|
|
12
|
+
entries: TelemetryEntry[];
|
|
13
|
+
}>;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { Telemetries } from '../client/journals.mjs';
|
|
2
|
+
import { resolveSessionId } from '../session.mjs';
|
|
3
|
+
import { optionalBoolean, optionalEntryFormat, optionalString } from './validate.mjs';
|
|
4
|
+
/**
|
|
5
|
+
* `telemetry_get` — args `{ sessionId?, agent?, archived?, format? }`.
|
|
6
|
+
* Defaults `sessionId` to the current session (same resolution as
|
|
7
|
+
* `telemetry_append`), so "read back what I just recorded" works with no
|
|
8
|
+
* arguments. Collects the async-iterable client read into a single
|
|
9
|
+
* response, since MCP tool results aren't naturally streaming to the
|
|
10
|
+
* model — the underlying read still streams internally (see
|
|
11
|
+
* `client/stream.mts`), for consistency/reuse with the CLI and library.
|
|
12
|
+
*/
|
|
13
|
+
export async function handleTelemetryGet(args, config) {
|
|
14
|
+
const sessionId = resolveSessionId(optionalString(args.sessionId, 'sessionId'));
|
|
15
|
+
const agent = optionalString(args.agent, 'agent');
|
|
16
|
+
const archived = optionalBoolean(args.archived, 'archived');
|
|
17
|
+
const format = optionalEntryFormat(args.format);
|
|
18
|
+
const query = { sessionId };
|
|
19
|
+
if (agent !== undefined)
|
|
20
|
+
query.agent = agent;
|
|
21
|
+
if (archived !== undefined)
|
|
22
|
+
query.archived = archived;
|
|
23
|
+
if (format !== undefined)
|
|
24
|
+
query.format = format;
|
|
25
|
+
const telemetries = new Telemetries(config);
|
|
26
|
+
const entries = [];
|
|
27
|
+
for await (const entry of telemetries.get(query))
|
|
28
|
+
entries.push(entry);
|
|
29
|
+
return { entries };
|
|
30
|
+
}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { ClientConfig, TelemetryEntry } from '../client/types.mjs';
|
|
2
|
+
/** `telemetry_patch` — args `{ patches: Array<{ id, archived?, data? }> }`. */
|
|
3
|
+
export declare function handleTelemetryPatch(args: Record<string, unknown>, config: ClientConfig): Promise<{
|
|
4
|
+
patched: TelemetryEntry[];
|
|
5
|
+
}>;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { Telemetries } from '../client/journals.mjs';
|
|
2
|
+
import { expectObject, optionalBoolean } from './validate.mjs';
|
|
3
|
+
function toPatchOp(value, index) {
|
|
4
|
+
const obj = expectObject(value, `patches[${index}]`);
|
|
5
|
+
if (typeof obj.id !== 'string')
|
|
6
|
+
throw new Error(`patches[${index}].id must be a string.`);
|
|
7
|
+
const patch = { id: obj.id };
|
|
8
|
+
const archived = optionalBoolean(obj.archived, `patches[${index}].archived`);
|
|
9
|
+
if (archived !== undefined)
|
|
10
|
+
patch.archived = archived;
|
|
11
|
+
if (obj.data !== undefined)
|
|
12
|
+
patch.data = expectObject(obj.data, `patches[${index}].data`);
|
|
13
|
+
return patch;
|
|
14
|
+
}
|
|
15
|
+
/** `telemetry_patch` — args `{ patches: Array<{ id, archived?, data? }> }`. */
|
|
16
|
+
export async function handleTelemetryPatch(args, config) {
|
|
17
|
+
if (!Array.isArray(args.patches))
|
|
18
|
+
throw new Error('"patches" must be an array.');
|
|
19
|
+
const patches = args.patches.map((item, index) => toPatchOp(item, index));
|
|
20
|
+
const telemetries = new Telemetries(config);
|
|
21
|
+
return { patched: await telemetries.patch(patches) };
|
|
22
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { TelemetryEntryFormat } from '../client/types.mjs';
|
|
2
|
+
/** Shared argument validation for MCP tool handlers — args arrive as untyped JSON. */
|
|
3
|
+
export declare function expectObject(value: unknown, field: string): Record<string, unknown>;
|
|
4
|
+
export declare function optionalString(value: unknown, field: string): string | undefined;
|
|
5
|
+
export declare function optionalBoolean(value: unknown, field: string): boolean | undefined;
|
|
6
|
+
export declare function optionalEntryFormat(value: unknown): TelemetryEntryFormat | undefined;
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/** Shared argument validation for MCP tool handlers — args arrive as untyped JSON. */
|
|
2
|
+
export function expectObject(value, field) {
|
|
3
|
+
if (typeof value !== 'object' || value === null || Array.isArray(value)) {
|
|
4
|
+
throw new Error(`"${field}" must be an object.`);
|
|
5
|
+
}
|
|
6
|
+
return value;
|
|
7
|
+
}
|
|
8
|
+
export function optionalString(value, field) {
|
|
9
|
+
if (value === undefined)
|
|
10
|
+
return undefined;
|
|
11
|
+
if (typeof value !== 'string')
|
|
12
|
+
throw new Error(`"${field}" must be a string.`);
|
|
13
|
+
return value;
|
|
14
|
+
}
|
|
15
|
+
export function optionalBoolean(value, field) {
|
|
16
|
+
if (value === undefined)
|
|
17
|
+
return undefined;
|
|
18
|
+
if (typeof value !== 'boolean')
|
|
19
|
+
throw new Error(`"${field}" must be a boolean.`);
|
|
20
|
+
return value;
|
|
21
|
+
}
|
|
22
|
+
export function optionalEntryFormat(value) {
|
|
23
|
+
if (value === undefined)
|
|
24
|
+
return undefined;
|
|
25
|
+
if (value === 'json' || value === 'jsonl')
|
|
26
|
+
return value;
|
|
27
|
+
throw new Error('"format" must be "json" or "jsonl".');
|
|
28
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
export interface ResolveSessionIdOptions {
|
|
2
|
+
/** Directory to search from. Defaults to `process.cwd()`. */
|
|
3
|
+
cwd?: string;
|
|
4
|
+
/** Environment to read fallback vars from. Defaults to `process.env`. */
|
|
5
|
+
env?: NodeJS.ProcessEnv;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* Resolves the session id to record telemetry under, in priority order:
|
|
9
|
+
*
|
|
10
|
+
* 1. An explicit id passed by the caller.
|
|
11
|
+
* 2. A hook-written state file at `.atel/session.json`, found by
|
|
12
|
+
* walking up from `cwd` to the nearest ancestor containing `.git` (the
|
|
13
|
+
* project root) — falling back to `cwd` itself if no `.git` is found.
|
|
14
|
+
* A missing or unparsable file is treated as absent, not an error.
|
|
15
|
+
* 3. `CLAUDE_CODE_SESSION_ID`.
|
|
16
|
+
* 4. `CODEX_THREAD_ID`.
|
|
17
|
+
* 5. A generated id (`crypto.randomUUID()`), memoized for the lifetime of
|
|
18
|
+
* this process so repeated calls with no other source agree.
|
|
19
|
+
*
|
|
20
|
+
* This is what makes a fresh session (e.g. after `/clear`) automatically
|
|
21
|
+
* start a fresh telemetry stream: a plugin hook rewrites the state file on
|
|
22
|
+
* `SessionStart`, and step 2 above is re-read from disk on every call.
|
|
23
|
+
*/
|
|
24
|
+
export declare function resolveSessionId(explicit?: string, options?: ResolveSessionIdOptions): string;
|
package/dist/session.mjs
ADDED
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { randomUUID } from 'node:crypto';
|
|
2
|
+
import { existsSync, readFileSync } from 'node:fs';
|
|
3
|
+
import { dirname, join } from 'node:path';
|
|
4
|
+
const SESSION_STATE_RELATIVE_PATH = '.atel/session.json';
|
|
5
|
+
// Memoizes ONLY the last-resort generated id, so repeated calls within one
|
|
6
|
+
// process agree on a session when no other source is available. The file
|
|
7
|
+
// and env lookups below are deliberately re-read on every call (never
|
|
8
|
+
// cached) so a long-lived process — e.g. the MCP stdio server — picks up a
|
|
9
|
+
// state file rewritten by the SessionStart hook (e.g. after `/clear`)
|
|
10
|
+
// without needing to restart.
|
|
11
|
+
let generatedFallback;
|
|
12
|
+
function findProjectRoot(startDir) {
|
|
13
|
+
let dir = startDir;
|
|
14
|
+
for (;;) {
|
|
15
|
+
if (existsSync(join(dir, '.git')))
|
|
16
|
+
return dir;
|
|
17
|
+
const parent = dirname(dir);
|
|
18
|
+
if (parent === dir)
|
|
19
|
+
return startDir;
|
|
20
|
+
dir = parent;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
function readSessionStateFile(cwd) {
|
|
24
|
+
const root = findProjectRoot(cwd);
|
|
25
|
+
const path = join(root, SESSION_STATE_RELATIVE_PATH);
|
|
26
|
+
if (!existsSync(path))
|
|
27
|
+
return undefined;
|
|
28
|
+
try {
|
|
29
|
+
const parsed = JSON.parse(readFileSync(path, 'utf8'));
|
|
30
|
+
return typeof parsed.sessionId === 'string' && parsed.sessionId.length > 0
|
|
31
|
+
? parsed.sessionId
|
|
32
|
+
: undefined;
|
|
33
|
+
}
|
|
34
|
+
catch {
|
|
35
|
+
return undefined;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Resolves the session id to record telemetry under, in priority order:
|
|
40
|
+
*
|
|
41
|
+
* 1. An explicit id passed by the caller.
|
|
42
|
+
* 2. A hook-written state file at `.atel/session.json`, found by
|
|
43
|
+
* walking up from `cwd` to the nearest ancestor containing `.git` (the
|
|
44
|
+
* project root) — falling back to `cwd` itself if no `.git` is found.
|
|
45
|
+
* A missing or unparsable file is treated as absent, not an error.
|
|
46
|
+
* 3. `CLAUDE_CODE_SESSION_ID`.
|
|
47
|
+
* 4. `CODEX_THREAD_ID`.
|
|
48
|
+
* 5. A generated id (`crypto.randomUUID()`), memoized for the lifetime of
|
|
49
|
+
* this process so repeated calls with no other source agree.
|
|
50
|
+
*
|
|
51
|
+
* This is what makes a fresh session (e.g. after `/clear`) automatically
|
|
52
|
+
* start a fresh telemetry stream: a plugin hook rewrites the state file on
|
|
53
|
+
* `SessionStart`, and step 2 above is re-read from disk on every call.
|
|
54
|
+
*/
|
|
55
|
+
export function resolveSessionId(explicit, options = {}) {
|
|
56
|
+
if (explicit)
|
|
57
|
+
return explicit;
|
|
58
|
+
const fromFile = readSessionStateFile(options.cwd ?? process.cwd());
|
|
59
|
+
if (fromFile)
|
|
60
|
+
return fromFile;
|
|
61
|
+
const env = options.env ?? process.env;
|
|
62
|
+
if (env.CLAUDE_CODE_SESSION_ID)
|
|
63
|
+
return env.CLAUDE_CODE_SESSION_ID;
|
|
64
|
+
if (env.CODEX_THREAD_ID)
|
|
65
|
+
return env.CODEX_THREAD_ID;
|
|
66
|
+
generatedFallback ??= randomUUID();
|
|
67
|
+
return generatedFallback;
|
|
68
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@jongleberry/atel",
|
|
3
|
+
"version": "0.0.0",
|
|
4
|
+
"description": "Client library, CLI, and MCP server for atel (Agent Telemetry) — a telemetry stream for autonomous agents.",
|
|
5
|
+
"homepage": "https://github.com/jonathanong/atel#readme",
|
|
6
|
+
"bugs": {
|
|
7
|
+
"url": "https://github.com/jonathanong/atel/issues"
|
|
8
|
+
},
|
|
9
|
+
"license": "MIT",
|
|
10
|
+
"repository": {
|
|
11
|
+
"type": "git",
|
|
12
|
+
"url": "https://github.com/jonathanong/atel",
|
|
13
|
+
"directory": "packages/atel"
|
|
14
|
+
},
|
|
15
|
+
"bin": {
|
|
16
|
+
"atel": "./dist/cli/index.mjs"
|
|
17
|
+
},
|
|
18
|
+
"files": [
|
|
19
|
+
"dist",
|
|
20
|
+
"README.md"
|
|
21
|
+
],
|
|
22
|
+
"type": "module",
|
|
23
|
+
"main": "./dist/index.mjs",
|
|
24
|
+
"types": "./dist/index.d.mts",
|
|
25
|
+
"exports": {
|
|
26
|
+
".": {
|
|
27
|
+
"types": "./dist/index.d.mts",
|
|
28
|
+
"import": "./dist/index.mjs",
|
|
29
|
+
"default": "./dist/index.mjs"
|
|
30
|
+
}
|
|
31
|
+
},
|
|
32
|
+
"publishConfig": {
|
|
33
|
+
"access": "public"
|
|
34
|
+
},
|
|
35
|
+
"scripts": {
|
|
36
|
+
"build": "tsc --project tsconfig.build.json",
|
|
37
|
+
"typecheck": "tsc --noEmit --project tsconfig.json"
|
|
38
|
+
},
|
|
39
|
+
"dependencies": {
|
|
40
|
+
"@modelcontextprotocol/sdk": "^1.29.0"
|
|
41
|
+
},
|
|
42
|
+
"engines": {
|
|
43
|
+
"node": ">=24.0.0"
|
|
44
|
+
}
|
|
45
|
+
}
|