@inixiative/agent-session 0.7.0 → 0.8.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 CHANGED
@@ -74,24 +74,37 @@ arrive as `rate_limit` events.
74
74
  ```ts
75
75
  import { createSession, TRANSPORTS } from "@inixiative/agent-session";
76
76
 
77
- const kind = "codex-app-server"; // or claude-cli, claude-agent-sdk
77
+ const kind = "codex-app-server"; // or claude-cli, claude-agent-sdk, muse-serve
78
78
  if (TRANSPORTS[kind].capabilities.interrupt === "acknowledged") { /* … */ }
79
79
  const session = createSession(kind, { cwd, model: "gpt-6-luna", env: { CODEX_HOME: profile } });
80
80
  ```
81
81
 
82
- | | claude-cli | codex-app-server | claude-agent-sdk | acp | api |
83
- |---|---|---|---|---|---|
84
- | Status | ✅ live | ✅ live | ✅ live | stub | stub |
85
- | Resume / fork | native / native | native / – | native / native | – | – |
86
- | Interrupt | acknowledged | acknowledged | acknowledged | – | – |
87
- | Push | – | steer | – | – | – |
88
- | Approvals | callback | callback | callback | – | – |
89
- | Limits stream / poll | ✅ / ✅ | ✅ / ✅ | ✅ / – | – | – |
90
- | Primed reset | fork | fork | – | – | – |
82
+ | | claude-cli | codex-app-server | muse-serve | claude-agent-sdk | acp | api |
83
+ |---|---|---|---|---|---|---|
84
+ | Status | ✅ live | ✅ live | ✅ live | ✅ live | stub | stub |
85
+ | Resume / fork | native / native | native / – | native / native | native / native | – | – |
86
+ | Interrupt | acknowledged | acknowledged | acknowledged | acknowledged | – | – |
87
+ | Push | – | steer | steer | – | – | – |
88
+ | Approvals | callback | callback | callback | callback | – | – |
89
+ | Limits stream / poll | ✅ / ✅ | ✅ / ✅ | ✅ / ✅ | ✅ / – | – | – |
90
+ | Primed reset | fork | fork | – | – | – | – |
91
91
 
92
92
  Codex runs only over `codex app-server --listen stdio://` (`CodexAppServerSession`);
93
93
  Codex CLI 0.155 has no `mcp-server` subcommand.
94
94
 
95
+ Muse Code runs over `muse serve` through Meta's `@muse-code/sdk` (`MuseSession`), pinned to
96
+ the CLI's version (1.4.14): a host serving another version is refused at start. It bills the
97
+ saved Muse login: metered keys and endpoints never reach it (nor Muse's own tool runs, which
98
+ inherit its environment: a repo command needing `OPENAI_API_KEY` will not see it under Muse),
99
+ and a resumed session must be on provider `meta`. Per-login isolation is `env: { XDG_CONFIG_HOME, XDG_DATA_HOME }` (login and
100
+ sessions). `musePermissions(mode)` maps the host modes to an explicit permission profile, because
101
+ the host default lets Muse's AI reviewer answer approvals instead of the gates. Questions arrive
102
+ through `onUserInput()`; unanswered ones are cancelled with a reason. An approval offering
103
+ no approve-once or reject choice is reported as an `error` event and left open (the turn ends
104
+ at its timeout). Work Muse starts itself
105
+ (cron firings, monitors, goals, reminder agents) is emitted too, marked
106
+ `unattributedReason: "task"` with a `task` lifecycle typed `muse-cron`, `muse-monitor`, ….
107
+
95
108
  Full matrix, notes and what is stubbed: [docs/transports-pools-routing.md](docs/transports-pools-routing.md).
96
109
 
97
110
  ### Tool gate
@@ -254,6 +267,7 @@ snapshots in the artifact but do not fabricate a completed-turn total.
254
267
  | Claude Code | ✅ shipped |
255
268
  | Codex app-server | ✅ shipped (`CodexAppServerSession`, `CodexPrimedSessions`) |
256
269
  | Claude Agent SDK | ✅ shipped (`ClaudeAgentSdkSession`; caller supplies `query`) |
270
+ | Muse Code | ✅ shipped (`MuseSession`, through `@muse-code/sdk`) |
257
271
  | ACP agents / direct API | typed stubs |
258
272
  | Gemini CLI | planned |
259
273
  | Grok CLI | planned (when its headless/stream mode matures) |
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@inixiative/agent-session",
3
- "version": "0.7.0",
3
+ "version": "0.8.0",
4
4
  "description": "Drive coding-agent CLIs as persistent, streaming, event-captured sessions over interchangeable transports, with primed decision sessions, subscription pools, routing, limit polling and continuity.",
5
5
  "type": "module",
6
6
  "main": "src/index.ts",
@@ -36,11 +36,12 @@
36
36
  ],
37
37
  "license": "MIT",
38
38
  "dependencies": {
39
- "@inixiative/json-rules": "^3.16.0"
39
+ "@inixiative/json-rules": "^3.16.0",
40
+ "@muse-code/sdk": "1.4.14"
40
41
  },
41
42
  "devDependencies": {
42
43
  "@biomejs/biome": "2.5.2",
43
- "@inixiative/config": "^0.5.166",
44
+ "@inixiative/config": "^0.5.173",
44
45
  "@types/bun": "1.4.4",
45
46
  "lefthook": "2.1.9",
46
47
  "typescript": "6.0.3"
@@ -11,7 +11,7 @@
11
11
  // captures every event for Oracle, and supports fork/interrupt.
12
12
  //
13
13
  // Implementations: ClaudeCodeSession, CodexAppServerSession,
14
- // ClaudeAgentSdkSession. How a model is reached is the session's transport
14
+ // ClaudeAgentSdkSession, MuseSession. How a model is reached is the session's transport
15
15
  // (see transport.ts); every transport implements this one contract.
16
16
  // ---------------------------------------------------------------------------
17
17
 
@@ -84,12 +84,13 @@ export class SessionTurnError extends Error {
84
84
  * session's cwd and config home: Claude found no transcript ("No conversation found with session
85
85
  * ID": cleaned up, deleted, or kept under another project directory or `CLAUDE_CONFIG_DIR`), or
86
86
  * Codex found no rollout ("no rollout found for thread id": deleted, or under another
87
- * `CODEX_HOME`). No turn ran. The caller decides what comes next, typically a fresh session seeded
87
+ * `CODEX_HOME`), or Muse answered `sessionNotFound` (deleted, under another `XDG_DATA_HOME`, or
88
+ * an ephemeral host that died with it). No turn ran. The caller decides what comes next, typically a fresh session seeded
88
89
  * from its own record of the conversation; `cwd` says where the lookup was made.
89
90
  */
90
91
  export class NativeBindingMissingError extends Error {
91
92
  constructor(
92
- readonly runtime: 'claude-code' | 'codex-app-server',
93
+ readonly runtime: 'claude-code' | 'codex-app-server' | 'muse',
93
94
  readonly binding: string,
94
95
  message: string,
95
96
  readonly cwd?: string,
package/src/index.ts CHANGED
@@ -67,8 +67,28 @@ export {
67
67
  type LimitWindow,
68
68
  limitUtilization,
69
69
  mergeLimits,
70
+ museLimitSnapshot,
70
71
  } from './limits';
71
72
  export { type LimitProbeOptions, probeClaudeLimits, probeCodexLimits } from './limits-probe';
73
+ // Muse Code adapter: one `muse serve` host per session through Meta's @muse-code/sdk.
74
+ export {
75
+ MUSE_SDK_VERSION,
76
+ type MuseApprovalMode,
77
+ type MuseConnect,
78
+ type MuseHost,
79
+ type MuseInitializeResult,
80
+ type MuseLaunch,
81
+ type MusePermissionProfile,
82
+ type MusePermissions,
83
+ type MuseReasoningEffort,
84
+ MuseSession,
85
+ type MuseSessionConfig,
86
+ type MuseUserInputAnswer,
87
+ type MuseUserInputHandler,
88
+ type MuseUserInputQuestion,
89
+ type MuseUserInputRequest,
90
+ musePermissions,
91
+ } from './muse-session';
72
92
  export {
73
93
  ContinuityError,
74
94
  type ContinuityRefusal,
package/src/limits.ts CHANGED
@@ -1,10 +1,10 @@
1
1
  // Subscription usage limits, normalized across runtimes. Account identity
2
2
  // (email, account/organization IDs) is never read into a snapshot.
3
3
 
4
- export type LimitRuntime = 'claude' | 'codex';
4
+ export type LimitRuntime = 'claude' | 'codex' | 'muse';
5
5
 
6
6
  export interface LimitWindow {
7
- /** Stable per runtime: Claude `five_hour`/`seven_day`/…, Codex `primary`/`secondary`. */
7
+ /** Stable per runtime: Claude `five_hour`/`seven_day`/…, Codex `primary`/`secondary`, Muse `window`/`weekly`. */
8
8
  readonly id: string;
9
9
  /** 0–100. */
10
10
  readonly usedPercent: number;
@@ -104,6 +104,42 @@ export function codexLimitSnapshot(
104
104
  };
105
105
  }
106
106
 
107
+ /**
108
+ * Muse `usage/read` result (`{ usage }`) or `usage/changed` params (the usage itself): the plan's
109
+ * rolling `window` (five hours) and `weekly` windows, in percent used. Meta reports the windows from
110
+ * its latest model response, so a host that has not served a turn yet reports none. `tier` is not read:
111
+ * on the wire it is a numeric id (the CLI shows the plan's name), not a label known to be account-free.
112
+ */
113
+ export function museLimitSnapshot(
114
+ value: unknown,
115
+ source: LimitSnapshot['source'],
116
+ observedAt = Date.now(),
117
+ ): LimitSnapshot | undefined {
118
+ const outer = object(value);
119
+ const usage = object(outer?.usage) ?? outer;
120
+ const rolling = object(usage?.window),
121
+ weekly = object(usage?.weekly);
122
+ const ms = (v: unknown) => (typeof v === 'number' && Number.isFinite(v) && v > 0 ? v : undefined);
123
+ const windows = [
124
+ ...window(
125
+ 'window',
126
+ percent(rolling?.usedPercent),
127
+ ms(rolling?.resetsAtMs),
128
+ typeof rolling?.windowDurationMins === 'number' ? rolling.windowDurationMins : undefined,
129
+ ),
130
+ ...window('weekly', percent(weekly?.usedPercent), ms(weekly?.resetsAtMs), 10_080),
131
+ ];
132
+ if (!windows.length) return undefined;
133
+ return {
134
+ runtime: 'muse',
135
+ source,
136
+ observedAt: ms(usage?.observedAtMs) ?? observedAt,
137
+ windows,
138
+ // Explicit both ways, so a later report clears a block an earlier one (or a quota stop) set.
139
+ blocked: windows.some((w) => w.usedPercent >= 100),
140
+ };
141
+ }
142
+
107
143
  /** Claude CLI stream-json `rate_limit_event.rate_limit_info`. Utilization is a 0–1 fraction. */
108
144
  export function claudeRateLimitSnapshot(
109
145
  info: unknown,