trajectories 0.1.1 → 0.1.3

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.
@@ -15,6 +15,7 @@ import { SCHEMA_VERSION } from "./schema.js";
15
15
  import { classifyReadStore, formatMismatchMessage, incompleteStoreMessage } from "./schema-gate.js";
16
16
  import type {
17
17
  CanonicalDbRecord,
18
+ IngestDiagnosticRecord,
18
19
  QueryResult,
19
20
  RecordMatchType,
20
21
  RecordSearchHit,
@@ -1220,6 +1221,26 @@ export class TrajectoryReader {
1220
1221
  return sessionRecords(this.db, sessionId);
1221
1222
  }
1222
1223
 
1224
+ /** Read normalization uncertainty without opening a writer or reviving a tombstone. */
1225
+ getSessionDiagnostics(sessionId: string): IngestDiagnosticRecord[] {
1226
+ if (!this.getSession(sessionId)) return [];
1227
+ return this.db.query<IngestDiagnosticRecord, [string]>(
1228
+ `SELECT session_id, source, code, occurrence_count, sample, first_seen_at, last_seen_at
1229
+ FROM ingest_diagnostics WHERE session_id = ? ORDER BY code ASC`,
1230
+ ).all(sessionId);
1231
+ }
1232
+
1233
+ /** Pin one source generation before sending its complete history to a remote. */
1234
+ readSessionForSync(sessionId: string): {
1235
+ session: SessionRecord; records: CanonicalDbRecord[]; diagnostics: IngestDiagnosticRecord[];
1236
+ } | null {
1237
+ return this.db.transaction(() => {
1238
+ const session = this.getSession(sessionId);
1239
+ if (!session) return null;
1240
+ return { session, records: this.getSessionRecords(sessionId), diagnostics: this.getSessionDiagnostics(sessionId) };
1241
+ }).deferred();
1242
+ }
1243
+
1223
1244
  getSessionCount(): number {
1224
1245
  return countSessions(this.db);
1225
1246
  }
@@ -0,0 +1,217 @@
1
+ import { closeSync, constants, existsSync, fstatSync, openSync, readFileSync } from 'node:fs';
2
+ import { mkdir } from 'node:fs/promises';
3
+ import { dirname, resolve } from 'node:path';
4
+ import { parseArgs } from 'node:util';
5
+ import { resolveCanonicalDbPath } from './canonical.js';
6
+ import { ensurePrivateDirectory } from './private-storage.js';
7
+ import { acquireWriterLease, isMemoryStorePath } from './writer-lease.js';
8
+ import { TrajectoryReader } from './reader.js';
9
+ import { TrajectoryDb } from './db.js';
10
+ import { listSessions } from '../../src/log.js';
11
+ import type { PageCursor } from '../../src/log-types.js';
12
+ import { TrajectoriesError } from '../../src/log-types.js';
13
+ import { exportManagedDelta } from '../../src/shared-managed.js';
14
+ import { safeId } from '../../src/log-io.js';
15
+ import { createSharedClient, createSharedHandler, sharedObservationId } from '../../src/shared.js';
16
+ import type { ObservedState } from '../../src/shared.js';
17
+
18
+ const help = `trajectories remote — cross-machine canonical history
19
+ remote serve --store <shared-directory> --token-file <0600-file>
20
+ [--host 127.0.0.1] [--port 8789]
21
+ remote push --url <endpoint> --token-file <0600-file> --machine <stable-id>
22
+ [--db <SQLite>] [--store <managed-store>] [--session <id>]
23
+ remote pull --url <endpoint> --token-file <0600-file> [--db <SQLite>]
24
+ [--store <managed-mirror>] [--machine <stable-origin-id>]
25
+ remote list --url <endpoint> --token-file <0600-file>
26
+ Token path fallback: TRAJECTORIES_REMOTE_TOKEN_FILE. Tokens never belong in URLs.
27
+ Push publishes observed canonical records; native files are not uploaded by this lane.
28
+ --store additionally synchronizes managed logs and their referenced objects.
29
+ Pull updates the existing SQLite lexical index; it never launches native harnesses.
30
+ Pull --machine skips that originating machine's observed rows already stored locally.
31
+ `;
32
+
33
+ function required(value: string | undefined, option: string): string {
34
+ if (!value) throw new Error(`${option} is required.`);
35
+ return value;
36
+ }
37
+
38
+ /** Read an owner-only regular file through the validated descriptor. */
39
+ function readToken(path: string): string {
40
+ const fd = openSync(path, constants.O_RDONLY | constants.O_NOFOLLOW);
41
+ try {
42
+ const stat = fstatSync(fd);
43
+ if (!stat.isFile() || stat.nlink !== 1 || (stat.mode & 0o777) !== 0o600 || (process.getuid && stat.uid !== process.getuid())) {
44
+ throw new Error('Remote token file must be an owner-owned regular file with mode 0600.');
45
+ }
46
+ if (stat.size > 4096) throw new Error('Remote token file is too large.');
47
+ const token = readFileSync(fd, 'utf8').trim();
48
+ if (!token || /[\s\x00-\x1f\x7f]/u.test(token)) throw new Error('Remote token file must contain one nonempty token.');
49
+ return token;
50
+ } finally { closeSync(fd); }
51
+ }
52
+
53
+ function project(state: ObservedState) {
54
+ const id = `shared:${state.id}`;
55
+ return {
56
+ session: { ...state.session, id, source_path: `shared://${state.machineId}/${encodeURIComponent(state.session.id)}`,
57
+ // The remote immutable head covers both record and metadata changes.
58
+ content_hash: state.head,
59
+ parent_session_id: state.session.parent_session_id
60
+ ? `shared:${sharedObservationId(state.machineId, state.session.parent_session_id)}` : null,
61
+ },
62
+ records: state.records.map(record => ({ ...record, id: `${id}:${record.id}`, session_id: id })),
63
+ };
64
+ }
65
+
66
+ export async function runSharedCli(argv: string[]): Promise<void> {
67
+ // Help must not open SQLite, managed stores, credentials or sockets.
68
+ if (!argv.length || argv.some(value => value === '--help' || value === '-h') || argv[0] === 'help') { console.log(help); return; }
69
+ const command = argv[0];
70
+ if (!['serve', 'push', 'pull', 'list'].includes(command!)) throw new Error('Expected remote serve, push, pull or list.');
71
+ const { values, positionals } = parseArgs({ args: argv.slice(1), strict: true, allowPositionals: true, options: {
72
+ store: { type: 'string' }, host: { type: 'string' }, port: { type: 'string' },
73
+ url: { type: 'string' }, 'token-file': { type: 'string' }, machine: { type: 'string' },
74
+ db: { type: 'string' }, session: { type: 'string' }, robot: { type: 'boolean' }, json: { type: 'boolean' },
75
+ }});
76
+ if (positionals.length) throw new Error('Unexpected remote positional arguments.');
77
+ const allowed: Record<string, Set<string>> = {
78
+ serve: new Set(['store', 'host', 'port', 'token-file', 'json', 'robot']),
79
+ push: new Set(['url', 'token-file', 'machine', 'db', 'store', 'session', 'json', 'robot']),
80
+ pull: new Set(['url', 'token-file', 'db', 'store', 'machine', 'json', 'robot']),
81
+ list: new Set(['url', 'token-file', 'json', 'robot']),
82
+ };
83
+ for (const option of Object.keys(values)) {
84
+ if (!allowed[command!]!.has(option)) throw new Error(`--${option} is not supported by remote ${command}.`);
85
+ }
86
+ const machine = values.machine === undefined ? undefined : safeId(values.machine);
87
+ const port = values.port === undefined ? 8789 : Number(values.port);
88
+ if (command === 'serve' && (!Number.isInteger(port) || port < 0 || port > 65535)) throw new Error('--port must be an integer from 0 through 65535.');
89
+ const token = readToken(required(values['token-file'] ?? process.env.TRAJECTORIES_REMOTE_TOKEN_FILE, '--token-file'));
90
+ const emit = (value: unknown) => console.log(JSON.stringify(value));
91
+ if (command === 'serve') {
92
+ const store = resolve(required(values.store, '--store'));
93
+ const server = Bun.serve({ hostname: values.host ?? '127.0.0.1', port,
94
+ maxRequestBodySize: 64 * 1024 * 1024, fetch: createSharedHandler({ store, token }),
95
+ });
96
+ const close = () => { server.stop(true); process.removeListener('SIGINT', close); process.removeListener('SIGTERM', close); };
97
+ process.on('SIGINT', close); process.on('SIGTERM', close);
98
+ emit({ command: 'serve', host: server.hostname, port: server.port });
99
+ return;
100
+ }
101
+ const client = createSharedClient({ url: required(values.url, '--url'), token });
102
+ if (command === 'list') {
103
+ const observed = await client.listObserved();
104
+ const managed = await client.listManaged();
105
+ emit({ observed: observed.map(item => ({ id: item.id, head: item.head, machineId: item.machineId,
106
+ source: item.session.source, records: item.session.record_count })),
107
+ managed: managed.map(item => ({ id: item.id, head: item.head })),
108
+ });
109
+ return;
110
+ }
111
+ const dbPath = values.db ?? resolveCanonicalDbPath();
112
+ if (command === 'push') {
113
+ const machineId = required(machine, '--machine');
114
+ const observed = [];
115
+ let selected = false;
116
+ // An explicit managed store without --db selects only the managed lane.
117
+ if (!values.store || values.db) {
118
+ const reader = new TrajectoryReader(dbPath);
119
+ try {
120
+ const ids = values.session ? [values.session] : reader.getAllSessions().map(session => session.id);
121
+ for (const id of ids) {
122
+ const captured = reader.readSessionForSync(id);
123
+ if (!captured) continue;
124
+ const { session, records } = captured;
125
+ // Derived mirrors and managed projections cannot become native originals.
126
+ if (session.source === 'managed' || session.id.startsWith('managed:') || session.source_path.startsWith('shared://')) continue;
127
+ selected = true;
128
+ const diagnostics = captured.diagnostics.map(item => ({ code: item.code,
129
+ occurrenceCount: item.occurrence_count, sample: item.sample, firstSeenAt: item.first_seen_at }));
130
+ observed.push(await client.pushObserved({ machineId, session: { ...session, diagnostics }, records }));
131
+ }
132
+ } finally { reader.close(); }
133
+ }
134
+ const managed = [];
135
+ if (values.store) {
136
+ const store = resolve(values.store);
137
+ let cursor: PageCursor | undefined;
138
+ do {
139
+ const page = await listSessions(store, { cursor, limit: 1000 });
140
+ for (const session of page.items) {
141
+ if (values.session && session.id !== values.session) continue;
142
+ selected = true;
143
+ managed.push(await client.pushManaged(store, session.id));
144
+ }
145
+ cursor = page.nextCursor ?? undefined;
146
+ } while (cursor);
147
+ }
148
+ if (values.session && !selected) throw new Error('Selected original session was not found; managed projections require --store.');
149
+ emit({ command, observed, managed });
150
+ return;
151
+ }
152
+ if (!isMemoryStorePath(dbPath)) {
153
+ if (!values.db && !process.env.TRAJECTORIES_DB && !process.env.LEDGER_DB) ensurePrivateDirectory(dirname(dbPath));
154
+ else await mkdir(dirname(dbPath), { recursive: true, mode: 0o700 });
155
+ }
156
+ const observed = [];
157
+ for (const item of await client.listObserved()) {
158
+ if (item.machineId === machine) {
159
+ observed.push({ id: item.id, head: item.head, outcome: 'skipped-origin' });
160
+ continue;
161
+ }
162
+ if (!isMemoryStorePath(dbPath) && existsSync(dbPath)) {
163
+ const reader = new TrajectoryReader(dbPath);
164
+ try {
165
+ const local = reader.getSession(`shared:${item.id}`);
166
+ if (local?.source_path.startsWith('shared://') && local.content_hash === item.head) {
167
+ observed.push({ id: item.id, head: item.head, records: local.record_count, outcome: 'unchanged' });
168
+ continue;
169
+ }
170
+ } finally { reader.close(); }
171
+ }
172
+ const state = await client.getObserved(item.id);
173
+ const lease = isMemoryStorePath(dbPath) ? null : acquireWriterLease(dbPath, { holder: 'trajectories remote pull' });
174
+ try {
175
+ const db = new TrajectoryDb(dbPath);
176
+ try {
177
+ const projection = project(state);
178
+ if (db.getTombstone(projection.session.id)) { observed.push({ id: item.id, head: state.head, outcome: 'deleted' }); continue; }
179
+ const saved = db.saveSession(projection.session, projection.records, state.session.diagnostics);
180
+ observed.push({ id: item.id, head: state.head, records: projection.records.length,
181
+ outcome: saved.inserted ? 'inserted' : saved.updated ? 'updated' : 'unchanged' });
182
+ } finally { db.close(); }
183
+ } finally { lease?.close(); }
184
+ }
185
+ const managed = [];
186
+ let conflicts = 0;
187
+ if (values.store) {
188
+ const store = resolve(values.store);
189
+ for (const session of await client.listManaged()) {
190
+ try { managed.push({ ...await client.pullManaged(store, session.id), outcome: 'pulled' }); }
191
+ catch (error) {
192
+ if (!(error instanceof TrajectoriesError) || !['STALE_HEAD', 'INTENT_CONFLICT'].includes(error.code)) throw error;
193
+ // The failed pull may have observed a newer branch than the original list.
194
+ const remote = (await client.listManaged()).find(item => item.id === session.id);
195
+ let ahead;
196
+ try { if (remote) ahead = await exportManagedDelta(store, session.id, { afterHead: remote.head }); }
197
+ catch (proofError) {
198
+ if (!(proofError instanceof TrajectoriesError) || !['STALE_HEAD', 'NOT_FOUND'].includes(proofError.code)) throw proofError;
199
+ }
200
+ if (remote && ahead?.frames.length && ahead.head !== remote.head) {
201
+ managed.push({ id: session.id, head: ahead.head, remoteHead: remote.head, outcome: 'ahead' });
202
+ } else {
203
+ conflicts++;
204
+ managed.push({ id: session.id, remoteHead: remote?.head, outcome: 'conflict', code: error.code });
205
+ }
206
+ }
207
+ }
208
+ // Existing indexer preserves accepted managed ordering, FTS and tombstones.
209
+ // Its summary is emitted separately and contains no record bodies.
210
+ if (managed.length) {
211
+ const { runManagedCli } = await import('./managed.js');
212
+ await runManagedCli('index', ['--store', resolve(values.store), '--db', dbPath, '--robot']);
213
+ }
214
+ }
215
+ emit({ command, observed, managed });
216
+ if (conflicts) throw new TrajectoriesError('STALE_HEAD', `${conflicts} managed session(s) conflict; other histories were pulled and indexed. Local branches were preserved.`);
217
+ }
@@ -630,12 +630,26 @@ function retryAt(now: Date, attempts: number): string {
630
630
  return new Date(now.getTime() + delayMs).toISOString();
631
631
  }
632
632
 
633
+ declare const TRAJECTORIES_STANDALONE: boolean;
634
+ declare const TRAJECTORIES_BUNDLED_CLI: boolean;
635
+
636
+ function syncEntry(command: string): string[] {
637
+ // Compiled distributions execute the same private verbs in a fresh process.
638
+ if (typeof TRAJECTORIES_STANDALONE !== "undefined" && TRAJECTORIES_STANDALONE) {
639
+ return [process.execPath, command];
640
+ }
641
+ if (typeof TRAJECTORIES_BUNDLED_CLI !== "undefined" && TRAJECTORIES_BUNDLED_CLI) {
642
+ return [process.execPath, process.argv[1]!, command];
643
+ }
644
+ return [process.execPath, fileURLToPath(new URL("../bin/ledger-core.ts", import.meta.url)), command];
645
+ }
646
+
633
647
  function workerEntry(): string[] {
634
- return [process.execPath, fileURLToPath(new URL("../bin/ledger-core.ts", import.meta.url)), "__sync-worker"];
648
+ return syncEntry("__sync-worker");
635
649
  }
636
650
 
637
651
  function maintenanceEntry(): string[] {
638
- return [process.execPath, fileURLToPath(new URL("../bin/ledger-core.ts", import.meta.url)), "__sync-maintenance"];
652
+ return syncEntry("__sync-maintenance");
639
653
  }
640
654
 
641
655
  export function workerReservation(
@@ -863,7 +877,7 @@ async function prepareInChild(options: SyncOptions, scanLimit: number, maxRecord
863
877
  if (remaining <= 0) throw new SyncPreparationError("timed_out");
864
878
  const result = await spawnJsonChild<SyncPreparationReply | PreparationFailure>({ protocol_version: SYNC_PROTOCOL_VERSION,
865
879
  db_path: options.dbPath, sources: options.sources, roots: options.roots, scan_limit: scanLimit, max_record_bytes: maxRecordBytes },
866
- remaining, options.preparationCommand ?? [process.execPath, fileURLToPath(new URL("../bin/ledger-core.ts", import.meta.url)), "__sync-prepare"],
880
+ remaining, options.preparationCommand ?? syncEntry("__sync-prepare"),
867
881
  parsePreparationReply, { label: "sync_preparation" });
868
882
  if (result.status !== "ok" || !result.reply) throw new SyncPreparationError(result.status);
869
883
  if (result.reply.type === "sync_preparation_error") {
package/ops/README.md CHANGED
@@ -7,10 +7,40 @@ session/log store, which requires an explicit `index --store` command.
7
7
 
8
8
  ## Install the CLI
9
9
 
10
+ ### Native CLI
11
+
12
+ Native releases require no Bun, Node or npm. The repository is currently private,
13
+ so GitHub downloads require an authenticated `gh` client with repository access.
14
+ On an Apple Silicon Mac:
15
+
16
+ ```sh
17
+ gh release download 'trajectories@0.1.2' --repo archeism/oh-my-ai \
18
+ --pattern 'trajectories-0.1.2-darwin-arm64.tar.gz*'
19
+ shasum -a 256 --check trajectories-0.1.2-darwin-arm64.tar.gz.sha256
20
+ mkdir -p "$HOME/.local/share/trajectories/native"
21
+ tar -xzf trajectories-0.1.2-darwin-arm64.tar.gz -C "$HOME/.local/share/trajectories/native"
22
+ bash "$HOME/.local/share/trajectories/native/trajectories-0.1.2-darwin-arm64/install.sh"
23
+ trajectories --version
24
+ ```
25
+
26
+ On Linux, choose `linux-x64` or `linux-arm64`, and use `sha256sum --check`.
27
+ The installer refuses existing commands unless `--force` explicitly authorizes
28
+ replacement. It creates a symlink to the retained release directory; do not
29
+ delete that directory or separate the executable from `lib/`. It does not change
30
+ the search database or enable an indexing service. Ensure `~/.local/bin` is on PATH.
31
+ Local ONNX inference requires glibc 2.28+ on Linux or macOS 14+ on Apple Silicon. Deep Agents SQLite conversion
32
+ still uses the harness's own Python/LangGraph environment.
33
+
34
+ The service installers below are for source/npm installations and invoke Bun.
35
+ For a native service, its command is the installed `trajectories sync` executable
36
+ directly; the CLI's bounded sync and scheduler protocol are unchanged.
37
+
38
+ ### npm or source CLI
39
+
10
40
  For the npm distribution, use Bun 1.4.2 or newer:
11
41
 
12
42
  ```sh
13
- bun add --global trajectories@0.1.0
43
+ bun add --global trajectories@0.1.2
14
44
  trajectories --version
15
45
  trajectories status --robot
16
46
  ```
@@ -0,0 +1,35 @@
1
+ #!/usr/bin/env bash
2
+ # Run from an extracted native release kept in a permanent directory.
3
+ set -euo pipefail
4
+ RELEASE_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd -P)"
5
+ BIN_DIR="${TRAJECTORIES_BIN_DIR:-$HOME/.local/bin}"
6
+ FORCE=0
7
+ while [[ $# -gt 0 ]]; do
8
+ case "$1" in
9
+ --bin-dir) [[ $# -ge 2 && -n "$2" ]] || { echo '--bin-dir requires a directory.' >&2; exit 1; }; BIN_DIR="$2"; shift 2 ;;
10
+ --force) FORCE=1; shift ;;
11
+ --help|-h) echo 'Usage: install.sh [--bin-dir DIR] [--force]'; exit 0 ;;
12
+ *) echo "Unknown option: $1" >&2; exit 1 ;;
13
+ esac
14
+ done
15
+ [[ -x "$RELEASE_DIR/trajectories" && -d "$RELEASE_DIR/lib" ]] || {
16
+ echo 'Keep install.sh, the trajectories executable, and lib/ together in the extracted release.' >&2; exit 1;
17
+ }
18
+ "$RELEASE_DIR/trajectories" --version
19
+ mkdir -p "$BIN_DIR"
20
+ TARGET="$BIN_DIR/trajectories"
21
+ if [[ -e "$TARGET" || -L "$TARGET" ]]; then
22
+ if [[ -L "$TARGET" && "$(readlink "$TARGET")" == "$RELEASE_DIR/trajectories" ]]; then
23
+ echo "Already installed: $TARGET"; exit 0
24
+ fi
25
+ [[ "$FORCE" == 1 && ! -d "$TARGET" ]] || {
26
+ echo "Refusing to overwrite $TARGET; use --force for an explicit cutover." >&2; exit 1;
27
+ }
28
+ fi
29
+ STAGE="$(mktemp -d "$BIN_DIR/.trajectories-install.XXXXXX")"
30
+ trap 'rm -rf "$STAGE"' EXIT
31
+ ln -s "$RELEASE_DIR/trajectories" "$STAGE/trajectories"
32
+ mv -f "$STAGE/trajectories" "$TARGET"
33
+ echo "Installed: $TARGET"
34
+ echo "Keep the release directory: $RELEASE_DIR"
35
+ case ":$PATH:" in *":$BIN_DIR:"*) ;; *) echo "Add $BIN_DIR to PATH." ;; esac
package/package.json CHANGED
@@ -1,22 +1,61 @@
1
1
  {
2
2
  "name": "trajectories",
3
- "version": "0.1.1",
3
+ "version": "0.1.3",
4
4
  "description": "Portable coding-agent sessions: read, search, convert, and continue across harnesses.",
5
5
  "type": "module",
6
6
  "license": "Apache-2.0",
7
- "engines": { "node": ">=22.13.0", "bun": ">=1.4.2" },
8
- "exports": { ".": { "types": "./dist/index.d.ts", "import": "./dist/index.js" } },
9
- "bin": { "trajectories": "./dist/cli.js" },
10
- "files": ["dist", "docs", "legacy/src", "legacy/bin", "legacy/scripts", "legacy/NOTICE.md", "ops", "skills", "README.md", "CHANGELOG.md", "LICENSE"],
7
+ "engines": {
8
+ "node": ">=22.13.0",
9
+ "bun": ">=1.4.2"
10
+ },
11
+ "exports": {
12
+ ".": {
13
+ "types": "./dist/index.d.ts",
14
+ "import": "./dist/index.js"
15
+ }
16
+ },
17
+ "bin": {
18
+ "trajectories": "./dist/cli.js"
19
+ },
20
+ "files": [
21
+ "dist",
22
+ "docs",
23
+ "legacy/src",
24
+ "legacy/bin",
25
+ "legacy/scripts",
26
+ "legacy/NOTICE.md",
27
+ "ops",
28
+ "skills",
29
+ "README.md",
30
+ "CHANGELOG.md",
31
+ "LICENSE"
32
+ ],
11
33
  "scripts": {
12
- "build": "tsc -p tsconfig.build.json && bun build src/index.ts --target node --format esm --outfile dist/index.js && bun build src/normalization-runtime.ts --target bun --format esm --outfile dist/normalization-runtime.js && bun build src/cli.ts --target bun --format esm --outfile dist/cli.js && bun -e \"require('node:fs').chmodSync('dist/cli.js', 0o755)\"",
34
+ "build": "tsc -p tsconfig.build.json && bun build src/index.ts --target node --format esm --outfile dist/index.js && bun build src/normalization-runtime.ts --target bun --format esm --outfile dist/normalization-runtime.js && bun build src/cli.ts --target bun --format esm --external onnxruntime-node --define TRAJECTORIES_BUNDLED_CLI=true --outfile dist/cli.js && bun scripts/build-assets.ts",
35
+ "build:native": "bun run build && bun scripts/build-native.ts",
13
36
  "test": "bun test ./test/*.test.ts",
14
37
  "verify": "bun run build && tsc -p tsconfig.legacy.json && bun run test && bun test ./legacy/tests",
15
- "test:package": "bun run build && bun test ./smoke/package.test.ts"
38
+ "test:native": "bun scripts/check-native.ts",
39
+ "test:package": "bun run build && bun test ./smoke/package.test.ts && bun run test:native"
40
+ },
41
+ "dependencies": {
42
+ "@letta-ai/trajectory": "0.4.3"
43
+ },
44
+ "optionalDependencies": {
45
+ "onnxruntime-node": "^1.29.0"
46
+ },
47
+ "devDependencies": {
48
+ "@types/node": "^22.20.1",
49
+ "@types/bun": "1.3.14",
50
+ "typescript": "^5.9.3"
51
+ },
52
+ "repository": {
53
+ "type": "git",
54
+ "url": "git+https://github.com/archeism/oh-my-ai.git",
55
+ "directory": "packages/trajectories"
56
+ },
57
+ "publishConfig": {
58
+ "access": "public"
16
59
  },
17
- "dependencies": { "@letta-ai/trajectory": "0.4.3" },
18
- "optionalDependencies": { "onnxruntime-node": "^1.29.0" },
19
- "devDependencies": { "@types/node": "^22.20.1", "@types/bun": "1.3.14", "typescript": "^5.9.3" },
20
- "repository": { "type": "git", "url": "git+https://github.com/archeism/oh-my-ai.git", "directory": "packages/trajectories" },
21
- "publishConfig": { "access": "public" }
60
+ "gitHead": "fa1591e54eaeec7d48a8edfaa086d46fd9b2d4f3"
22
61
  }
package/dist/cli.d.ts DELETED
@@ -1,2 +0,0 @@
1
- #!/usr/bin/env bun
2
- export {};