@trama-dev/session 0.1.5

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 ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 trama contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,41 @@
1
+ # @trama-dev/session
2
+
3
+ > Multi-agent coordination for trama programs.
4
+
5
+ The session layer for [trama](https://github.com/NaNhkNaN/trama) — shared workspace, cooperative suspension, and structured program results for coordinating multiple agent-authored programs.
6
+
7
+ ## Usage
8
+
9
+ ```typescript
10
+ import { ctx, agent, tools, workspace } from "@trama-dev/runtime";
11
+ import { Session } from "@trama-dev/session";
12
+
13
+ const session = await Session.createTemp();
14
+
15
+ // Spawn participants — each is a full trama program
16
+ const handle = session.spawn("check-sql", {
17
+ projectDir: "~/.trama/projects/check-sql",
18
+ });
19
+
20
+ const result = await handle.wait();
21
+ // { status: "done" | "yielded" | "failed", reason?, result? }
22
+
23
+ // Resume a yielded participant
24
+ if (result.status === "yielded") {
25
+ const resumed = await handle.resume({ feedback: "approved" });
26
+ await resumed.wait();
27
+ }
28
+ ```
29
+
30
+ ## What the session layer provides
31
+
32
+ - **Shared workspace** — participants read and write artifacts through a common directory with atomic writes and path guarding.
33
+ - **Structured results** — `ProgramResult` with `status`, `reason`, and `result` fields. The session layer never reads `state.json` directly.
34
+ - **Yield/resume** — participants can suspend cooperatively via `ctx.yield()` and be resumed with new args.
35
+ - **Failure isolation** — each participant has its own trama lifecycle, repair loop, and state. A crashing participant doesn't corrupt the workspace or block others.
36
+
37
+ ## Design
38
+
39
+ The session layer is **policy**. The runtime is **mechanism**. The session manages coordination (who participates, when to resume). The runtime manages execution (state persistence, auto-repair, version history). This boundary is enforced: `session` depends on `runtime`, never the reverse.
40
+
41
+ See the [main README](https://github.com/NaNhkNaN/trama) for the full API reference, and [docs/workspace-rfc.md](https://github.com/NaNhkNaN/trama/blob/main/docs/workspace-rfc.md) for the design rationale.
@@ -0,0 +1,47 @@
1
+ import type { ProgramResult } from "@trama-dev/runtime/runner";
2
+ export type { ProgramResult };
3
+ export interface SessionOptions {
4
+ /** Directory for shared workspace artifacts. Created if it doesn't exist. */
5
+ workspace: string;
6
+ }
7
+ export interface SpawnOptions {
8
+ /** Path to the trama project directory. */
9
+ projectDir: string;
10
+ /** Arguments passed to the program via ctx.input.args. */
11
+ args?: Record<string, unknown>;
12
+ /** Per-phase timeout in ms. */
13
+ timeout?: number;
14
+ /** Max repair attempts. */
15
+ maxRepairAttempts?: number;
16
+ }
17
+ export interface ParticipantHandle {
18
+ /** The participant name. */
19
+ name: string;
20
+ /** Wait for participant to complete, yield, or fail. */
21
+ wait(): Promise<ProgramResult>;
22
+ /**
23
+ * Resume a yielded participant with optional new args.
24
+ * Throws if the participant is not in a yielded state.
25
+ */
26
+ resume(args?: Record<string, unknown>): Promise<ParticipantHandle>;
27
+ }
28
+ export declare class Session {
29
+ /** The shared workspace directory path. */
30
+ readonly workspace: string;
31
+ private constructor();
32
+ /**
33
+ * Create a new session with a shared workspace directory.
34
+ * The workspace is created if it doesn't exist.
35
+ */
36
+ static create(options: SessionOptions): Promise<Session>;
37
+ /**
38
+ * Create a new session with a temporary workspace directory.
39
+ * Useful for testing or ephemeral sessions.
40
+ */
41
+ static createTemp(prefix?: string): Promise<Session>;
42
+ /**
43
+ * Spawn a trama program as a session participant.
44
+ * The program gets access to the shared workspace via the workspace API.
45
+ */
46
+ spawn(name: string, options: SpawnOptions): ParticipantHandle;
47
+ }
package/dist/index.js ADDED
@@ -0,0 +1,87 @@
1
+ import { mkdirSync, existsSync, mkdtempSync } from "fs";
2
+ import { resolve } from "path";
3
+ import { tmpdir } from "os";
4
+ import { runProgram } from "@trama-dev/runtime/runner";
5
+ export class Session {
6
+ /** The shared workspace directory path. */
7
+ workspace;
8
+ constructor(workspace) {
9
+ this.workspace = workspace;
10
+ }
11
+ /**
12
+ * Create a new session with a shared workspace directory.
13
+ * The workspace is created if it doesn't exist.
14
+ */
15
+ static async create(options) {
16
+ const workspace = resolve(options.workspace);
17
+ mkdirSync(workspace, { recursive: true });
18
+ return new Session(workspace);
19
+ }
20
+ /**
21
+ * Create a new session with a temporary workspace directory.
22
+ * Useful for testing or ephemeral sessions.
23
+ */
24
+ static async createTemp(prefix = "trama-session-") {
25
+ if (prefix.includes("/") || prefix.includes("\\")) {
26
+ throw new Error("createTemp prefix must not contain path separators");
27
+ }
28
+ const workspace = mkdtempSync(resolve(tmpdir(), prefix));
29
+ return new Session(workspace);
30
+ }
31
+ /**
32
+ * Spawn a trama program as a session participant.
33
+ * The program gets access to the shared workspace via the workspace API.
34
+ */
35
+ spawn(name, options) {
36
+ const { projectDir, args, timeout, maxRepairAttempts } = options;
37
+ const workspaceDir = this.workspace;
38
+ if (!existsSync(projectDir)) {
39
+ throw new Error(`Project directory not found: ${projectDir}`);
40
+ }
41
+ // Track participant lifecycle state
42
+ let state = "running";
43
+ let resultPromise;
44
+ // Track the latest effective args so multi-yield resumes accumulate state
45
+ let lastArgs = args;
46
+ const startRun = (runArgs) => {
47
+ state = "running";
48
+ lastArgs = runArgs;
49
+ const promise = runProgram({
50
+ projectDir,
51
+ timeout,
52
+ maxRepairAttempts,
53
+ args: runArgs ?? args,
54
+ workspaceDir,
55
+ });
56
+ // Track state transitions when the run completes
57
+ promise.then((result) => {
58
+ state = result.status === "yielded" ? "yielded"
59
+ : result.status === "done" ? "done"
60
+ : "failed";
61
+ }, () => {
62
+ // Infrastructure error — treat as failed
63
+ state = "failed";
64
+ });
65
+ return promise;
66
+ };
67
+ // Start the run immediately
68
+ resultPromise = startRun(args);
69
+ const handle = {
70
+ name,
71
+ wait() {
72
+ return resultPromise;
73
+ },
74
+ async resume(newArgs) {
75
+ // Fail-fast: check current state synchronously — don't block on a running participant
76
+ if (state !== "yielded") {
77
+ throw new Error(`Cannot resume participant "${name}": expected state "yielded" but got "${state}". ` +
78
+ `resume() is only valid after a program calls ctx.yield().`);
79
+ }
80
+ const mergedArgs = newArgs ? { ...(lastArgs ?? {}), ...newArgs } : lastArgs;
81
+ resultPromise = startRun(mergedArgs);
82
+ return handle;
83
+ },
84
+ };
85
+ return handle;
86
+ }
87
+ }
package/package.json ADDED
@@ -0,0 +1,38 @@
1
+ {
2
+ "name": "@trama-dev/session",
3
+ "version": "0.1.5",
4
+ "type": "module",
5
+ "exports": {
6
+ ".": {
7
+ "types": "./dist/index.d.ts",
8
+ "import": "./dist/index.js"
9
+ }
10
+ },
11
+ "scripts": {
12
+ "build": "tsc"
13
+ },
14
+ "publishConfig": {
15
+ "access": "public"
16
+ },
17
+ "description": "Agent session protocol for trama — multi-agent coordination with shared workspace",
18
+ "license": "MIT",
19
+ "repository": {
20
+ "type": "git",
21
+ "url": "https://github.com/NaNhkNaN/trama.git",
22
+ "directory": "packages/session"
23
+ },
24
+ "homepage": "https://github.com/NaNhkNaN/trama",
25
+ "bugs": "https://github.com/NaNhkNaN/trama/issues",
26
+ "files": [
27
+ "dist",
28
+ "README.md",
29
+ "LICENSE"
30
+ ],
31
+ "os": ["darwin", "linux"],
32
+ "dependencies": {
33
+ "@trama-dev/runtime": "0.1.5"
34
+ },
35
+ "devDependencies": {
36
+ "@types/node": "^25.5.0"
37
+ }
38
+ }