praxis-agent 0.35.0 → 0.37.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.
Files changed (111) hide show
  1. package/README.md +20 -2
  2. package/dist/application/background-agent-manager.d.ts +16 -6
  3. package/dist/application/background-agent-manager.js +139 -97
  4. package/dist/application/context-engine.d.ts +56 -0
  5. package/dist/application/context-engine.js +129 -0
  6. package/dist/application/durable-follow-up.d.ts +14 -0
  7. package/dist/application/durable-follow-up.js +52 -0
  8. package/dist/application/native-session-transcript.d.ts +72 -0
  9. package/dist/application/native-session-transcript.js +351 -0
  10. package/dist/application/native-sidechain-transcript.d.ts +34 -0
  11. package/dist/application/native-sidechain-transcript.js +156 -0
  12. package/dist/application/session-service.d.ts +23 -4
  13. package/dist/application/session-service.js +1130 -494
  14. package/dist/application/subagent-service.d.ts +5 -1
  15. package/dist/application/subagent-service.js +749 -320
  16. package/dist/application/team-agent-runtime.d.ts +29 -0
  17. package/dist/application/team-agent-runtime.js +169 -0
  18. package/dist/application/team-capability.d.ts +27 -0
  19. package/dist/application/team-capability.js +41 -0
  20. package/dist/application/team-lead-operations.d.ts +38 -0
  21. package/dist/application/team-lead-operations.js +155 -0
  22. package/dist/application/team-mailbox.d.ts +54 -0
  23. package/dist/application/team-mailbox.js +196 -0
  24. package/dist/application/team-manager.d.ts +113 -0
  25. package/dist/application/team-manager.js +681 -0
  26. package/dist/application/team-workspace.d.ts +29 -0
  27. package/dist/application/team-workspace.js +197 -0
  28. package/dist/application/top-level-agent-manager.d.ts +1 -0
  29. package/dist/application/top-level-agent-manager.js +1025 -403
  30. package/dist/application/transcript-projection.d.ts +35 -0
  31. package/dist/application/transcript-projection.js +139 -0
  32. package/dist/application/turn-lifecycle.d.ts +2 -0
  33. package/dist/application/turn-memory-coordinator.d.ts +43 -0
  34. package/dist/application/turn-memory-coordinator.js +98 -0
  35. package/dist/cli/agents-dashboard.js +10 -5
  36. package/dist/cli/interactive.d.ts +7 -0
  37. package/dist/cli/interactive.js +645 -334
  38. package/dist/cli/tui/claude-style.d.ts +8 -25
  39. package/dist/cli/tui/claude-style.js +299 -277
  40. package/dist/cli/tui/decision-surface-model.d.ts +71 -0
  41. package/dist/cli/tui/decision-surface-model.js +131 -0
  42. package/dist/cli/tui/decision-surface.d.ts +7 -0
  43. package/dist/cli/tui/decision-surface.js +41 -0
  44. package/dist/cli/tui/help-surface-model.d.ts +68 -0
  45. package/dist/cli/tui/help-surface-model.js +131 -0
  46. package/dist/cli/tui/mcp-panel.js +1 -2
  47. package/dist/cli/tui/permission-surface-model.d.ts +195 -0
  48. package/dist/cli/tui/permission-surface-model.js +360 -0
  49. package/dist/cli/tui/permission-surface.d.ts +7 -0
  50. package/dist/cli/tui/permission-surface.js +69 -0
  51. package/dist/cli/tui/presentation-environment.d.ts +32 -0
  52. package/dist/cli/tui/presentation-environment.js +149 -0
  53. package/dist/cli/tui/task-panel.js +10 -1
  54. package/dist/cli/tui/theme.d.ts +46 -3
  55. package/dist/cli/tui/theme.js +414 -56
  56. package/dist/cli/tui/tool-permission.js +16 -8
  57. package/dist/cli/tui/transcript-presentation.d.ts +19 -1
  58. package/dist/cli/tui/transcript-presentation.js +26 -6
  59. package/dist/cli/tui/transcript-viewport.d.ts +18 -0
  60. package/dist/cli/tui/transcript-viewport.js +517 -111
  61. package/dist/cli/tui/transcript-window-model.d.ts +108 -0
  62. package/dist/cli/tui/transcript-window-model.js +772 -0
  63. package/dist/cli/tui/tui-interaction-router.d.ts +78 -0
  64. package/dist/cli/tui/tui-interaction-router.js +127 -0
  65. package/dist/cli/tui/tui-screen-model.d.ts +114 -0
  66. package/dist/cli/tui/tui-screen-model.js +210 -0
  67. package/dist/cli/tui/tui-view-model.d.ts +2 -49
  68. package/dist/cli/tui/tui-view-model.js +1 -68
  69. package/dist/cli-runtime.d.ts +4 -2
  70. package/dist/cli-runtime.js +397 -32
  71. package/dist/compatibility/claude/transcript-codec.js +6 -0
  72. package/dist/core/agent-orchestration.d.ts +31 -0
  73. package/dist/core/agent-orchestration.js +235 -0
  74. package/dist/core/permission-policy.d.ts +4 -0
  75. package/dist/core/permission-policy.js +21 -0
  76. package/dist/core/runtime.d.ts +6 -0
  77. package/dist/core/runtime.js +20 -2
  78. package/dist/core/team-mailbox.d.ts +54 -0
  79. package/dist/core/team-mailbox.js +212 -0
  80. package/dist/core/team-ownership.d.ts +84 -0
  81. package/dist/core/team-ownership.js +505 -0
  82. package/dist/core/tool-execution-scheduler.js +6 -1
  83. package/dist/core/transcript-event.d.ts +5 -1
  84. package/dist/core/transcript-event.js +12 -0
  85. package/dist/persistence/claude-job-store.d.ts +58 -0
  86. package/dist/persistence/claude-job-store.js +483 -1
  87. package/dist/persistence/claude-transcript-store.d.ts +2 -1
  88. package/dist/persistence/claude-transcript-store.js +2 -10
  89. package/dist/persistence/native-team-mailbox.d.ts +68 -0
  90. package/dist/persistence/native-team-mailbox.js +542 -0
  91. package/dist/persistence/native-team-store.d.ts +34 -0
  92. package/dist/persistence/native-team-store.js +257 -0
  93. package/dist/persistence/native-transcript-reader.d.ts +53 -0
  94. package/dist/persistence/native-transcript-reader.js +283 -0
  95. package/dist/persistence/native-transcript-store.d.ts +69 -0
  96. package/dist/persistence/native-transcript-store.js +321 -0
  97. package/dist/persistence/subagent-lifecycle-store.d.ts +41 -8
  98. package/dist/persistence/subagent-lifecycle-store.js +373 -146
  99. package/dist/persistence/transcript-file-append.d.ts +2 -0
  100. package/dist/persistence/transcript-file-append.js +10 -0
  101. package/dist/platform/exclusive-file-lease.d.ts +3 -0
  102. package/dist/platform/exclusive-file-lease.js +3 -0
  103. package/dist/tools/claude-capabilities.d.ts +4 -0
  104. package/dist/tools/claude-capabilities.js +18 -2
  105. package/dist/tools/team-lead-tools.d.ts +19 -0
  106. package/dist/tools/team-lead-tools.js +479 -0
  107. package/dist/tools/team-member-tools.d.ts +21 -0
  108. package/dist/tools/team-member-tools.js +259 -0
  109. package/package.json +1 -1
  110. package/dist/cli/tui/fullscreen-renderer.d.ts +0 -14
  111. package/dist/cli/tui/fullscreen-renderer.js +0 -13
@@ -0,0 +1,156 @@
1
+ import { mkdir, open, readFile, rm } from 'node:fs/promises';
2
+ import { basename, isAbsolute, resolve } from 'node:path';
3
+ import { NativeSessionTranscript, } from './native-session-transcript.js';
4
+ import { NativeTranscriptStore } from '../persistence/native-transcript-store.js';
5
+ const permissionModes = new Set([
6
+ 'acceptEdits',
7
+ 'auto',
8
+ 'bypassPermissions',
9
+ 'default',
10
+ 'dontAsk',
11
+ 'plan',
12
+ ]);
13
+ const requiredKeys = [
14
+ 'agentType',
15
+ 'description',
16
+ 'toolUseId',
17
+ 'spawnDepth',
18
+ 'cwd',
19
+ 'promptId',
20
+ ];
21
+ const optionalKeys = [
22
+ 'name',
23
+ 'permissionMode',
24
+ 'isolation',
25
+ 'parentAgentId',
26
+ 'worktreePath',
27
+ ];
28
+ function nonBlank(value) {
29
+ return (typeof value === 'string' &&
30
+ value.trim().length > 0 &&
31
+ !value.includes('\0'));
32
+ }
33
+ function assertPaths(paths) {
34
+ for (const value of [
35
+ paths.sessionId,
36
+ paths.agentId,
37
+ paths.directory,
38
+ paths.transcriptFile,
39
+ paths.metadataFile,
40
+ ]) {
41
+ if (!nonBlank(value))
42
+ throw new Error('native sidechain paths are invalid');
43
+ }
44
+ if (!isAbsolute(paths.directory) ||
45
+ !isAbsolute(paths.transcriptFile) ||
46
+ !isAbsolute(paths.metadataFile))
47
+ throw new Error('native sidechain paths must be absolute');
48
+ const directory = resolve(paths.directory);
49
+ if (resolve(paths.transcriptFile) !==
50
+ resolve(directory, `agent-${paths.agentId}.jsonl`) ||
51
+ resolve(paths.metadataFile) !==
52
+ resolve(directory, `agent-${paths.agentId}.meta.json`) ||
53
+ basename(paths.transcriptFile) !== `agent-${paths.agentId}.jsonl` ||
54
+ basename(paths.metadataFile) !== `agent-${paths.agentId}.meta.json`)
55
+ throw new Error('native sidechain paths do not match agent identity');
56
+ if (paths.lockFile !== undefined &&
57
+ (!nonBlank(paths.lockFile) || !isAbsolute(paths.lockFile)))
58
+ throw new Error('native sidechain lock path is invalid');
59
+ }
60
+ function validateMetadata(value) {
61
+ if (!value || typeof value !== 'object' || Array.isArray(value))
62
+ throw new Error('native sidechain metadata must be an object');
63
+ const record = value;
64
+ if (Object.keys(record).some((key) => !requiredKeys.includes(key) && !optionalKeys.includes(key)))
65
+ throw new Error('native sidechain metadata contains unknown fields');
66
+ if (requiredKeys.some((key) => !(key in record)))
67
+ throw new Error('native sidechain metadata is invalid');
68
+ if (![record.agentType, record.description, record.toolUseId].every(nonBlank))
69
+ throw new Error('native sidechain metadata is invalid');
70
+ if (!Number.isSafeInteger(record.spawnDepth) ||
71
+ Number(record.spawnDepth) <= 0)
72
+ throw new Error('native sidechain metadata is invalid');
73
+ if (!nonBlank(record.cwd) || !isAbsolute(record.cwd))
74
+ throw new Error('native sidechain metadata cwd is invalid');
75
+ if (!nonBlank(record.promptId))
76
+ throw new Error('native sidechain metadata promptId is invalid');
77
+ if (record.name !== undefined && !nonBlank(record.name))
78
+ throw new Error('native sidechain metadata name is invalid');
79
+ if (record.permissionMode !== undefined &&
80
+ (typeof record.permissionMode !== 'string' ||
81
+ !permissionModes.has(record.permissionMode)))
82
+ throw new Error('native sidechain metadata permissionMode is invalid');
83
+ if (record.isolation !== undefined && record.isolation !== 'worktree')
84
+ throw new Error('native sidechain metadata isolation is invalid');
85
+ if (record.parentAgentId !== undefined &&
86
+ (typeof record.parentAgentId !== 'string' ||
87
+ !/^a[0-9a-f]{16}$/u.test(record.parentAgentId)))
88
+ throw new Error('native sidechain metadata parentAgentId is invalid');
89
+ if (record.worktreePath !== undefined &&
90
+ (!nonBlank(record.worktreePath) || !isAbsolute(record.worktreePath)))
91
+ throw new Error('native sidechain metadata worktreePath is invalid');
92
+ return {
93
+ ...record,
94
+ spawnDepth: Number(record.spawnDepth),
95
+ };
96
+ }
97
+ export class NativeSidechainTranscript {
98
+ paths;
99
+ transcript;
100
+ store;
101
+ constructor(paths) {
102
+ this.paths = paths;
103
+ assertPaths(paths);
104
+ this.store = new NativeTranscriptStore({
105
+ transcriptFile: paths.transcriptFile,
106
+ lockFile: paths.lockFile ?? `${paths.transcriptFile}.lock`,
107
+ });
108
+ this.transcript = new NativeSessionTranscript({
109
+ sessionId: paths.sessionId,
110
+ store: this.store,
111
+ });
112
+ }
113
+ async create(prompt, metadata) {
114
+ if (!nonBlank(prompt))
115
+ throw new Error('native sidechain prompt must not be blank');
116
+ const checked = validateMetadata(metadata);
117
+ await mkdir(this.paths.directory, { recursive: true });
118
+ let created = false;
119
+ try {
120
+ const handle = await open(this.paths.metadataFile, 'wx');
121
+ created = true;
122
+ try {
123
+ await handle.writeFile(`${JSON.stringify(checked)}\n`);
124
+ await handle.sync();
125
+ }
126
+ finally {
127
+ await handle.close();
128
+ }
129
+ await this.transcript.withLease({ kind: 'start' }, async (lease) => {
130
+ await lease.appendMessages({
131
+ messages: [{ role: 'user', content: prompt }],
132
+ });
133
+ });
134
+ }
135
+ catch (error) {
136
+ if (created)
137
+ await rm(this.paths.metadataFile, { force: true });
138
+ throw error;
139
+ }
140
+ }
141
+ withLease(operation) {
142
+ return this.transcript.withLease({ kind: 'resume' }, operation);
143
+ }
144
+ async loadReadOnly() {
145
+ const snapshot = await this.store.loadReadOnly();
146
+ if (snapshot.issue)
147
+ throw new Error(`Invalid native sidechain transcript: ${snapshot.issue.message}`);
148
+ if (snapshot.records.some((record) => record.event.sessionId !== this.paths.sessionId))
149
+ throw new Error('native sidechain transcript sessionId does not match paths');
150
+ return snapshot;
151
+ }
152
+ async metadata() {
153
+ return validateMetadata(JSON.parse(await readFile(this.paths.metadataFile, 'utf8')));
154
+ }
155
+ }
156
+ //# sourceMappingURL=native-sidechain-transcript.js.map
@@ -2,7 +2,7 @@ import { type AgentColorName, type AgentColorSelection } from '../compatibility/
2
2
  import type { ClaudeConditionalRuleResolver } from '../compatibility/claude/context.js';
3
3
  import { type DataPlane } from '../persistence/data-plane.js';
4
4
  import { type ClaudeFileResource, type ClaudeFileResourceConfig } from '../compatibility/claude/file-resources.js';
5
- import { type ClaudeDisplayTranscriptItem } from '../compatibility/claude/projection.js';
5
+ import type { TranscriptDisplayItem } from './transcript-projection.js';
6
6
  import { type ClaudeTranscriptEntry } from '../compatibility/claude/schema.js';
7
7
  import { type ClaudeSessionMetadata } from '../compatibility/claude/session-metadata.js';
8
8
  import { type ClaudeInterruptionClassification } from '../compatibility/claude/interruption.js';
@@ -15,6 +15,7 @@ import { type ContextAssembler } from '../core/context.js';
15
15
  import type { ClaudeExtensionCatalog } from '../extensions/claude-extensions.js';
16
16
  import type { ClaudeHookRunner } from '../hooks/claude-hooks.js';
17
17
  import { type TranscriptParseIssue } from '../persistence/claude-transcript-store.js';
18
+ import type { TranscriptCodecDiagnostic } from '../core/transcript-codec.js';
18
19
  import type { ClaudeCostStateStore } from '../persistence/claude-cost-state-store.js';
19
20
  import { type AgentPermissionMode } from './subagent-service.js';
20
21
  import { type ScheduledPrompt } from './scheduled-prompt-manager.js';
@@ -26,10 +27,14 @@ import { type ClaudeToolRole } from '../tools/claude-capabilities.js';
26
27
  import type { ClaudeInteractiveToolManager } from '../tools/claude-interactive-tools.js';
27
28
  import type { ClaudePermissionMode } from '../permissions/claude-permission-resolver.js';
28
29
  import type { ClaudeMcpRuntime, ClaudeMcpServerStatus, ClaudeMcpToolInspection } from '../mcp/claude-mcp-tools.js';
30
+ import type { TeamLeadOperations } from './team-lead-operations.js';
31
+ type TeamLeadToolRegistryFactory = (base: ToolRegistry, operations: TeamLeadOperations, sessionId: string, enabledTools: readonly string[]) => ToolRegistry;
29
32
  export interface ClaudeSessionServiceOptions {
30
33
  configRoot: string;
31
34
  /** `claude` preserves the legacy shared layout; the CLI selects `native` by default. */
32
35
  dataPlane?: DataPlane;
36
+ /** Experimental canonical native transcript writes. */
37
+ experimentalNativeTranscriptWrites?: boolean;
33
38
  cwd: string;
34
39
  claudeVersion: string;
35
40
  provider?: ModelProvider;
@@ -55,6 +60,7 @@ export interface ClaudeSessionServiceOptions {
55
60
  subagentToolNames?: readonly string[];
56
61
  taskToolNames?: readonly string[];
57
62
  scheduledToolNames?: readonly string[];
63
+ teamToolNames?: readonly string[];
58
64
  /** Runtime gates for Claude capability-driven tool exposure. */
59
65
  toolRole?: ClaudeToolRole;
60
66
  toolCapabilityEnvironment?: Readonly<Record<string, string | undefined>>;
@@ -103,6 +109,10 @@ export interface ClaudeSessionServiceOptions {
103
109
  interactiveTools?: ClaudeInteractiveToolManager;
104
110
  mcp?: ClaudeMcpRuntime;
105
111
  costStateStore?: Pick<ClaudeCostStateStore, 'load' | 'save'>;
112
+ /** Shared internal Team lead operations port. */
113
+ teamLeadOperations?: TeamLeadOperations;
114
+ /** Lazily supplied Team tool wrapper, so disabled runs do not load Team code. */
115
+ teamLeadToolRegistryFactory?: TeamLeadToolRegistryFactory;
106
116
  }
107
117
  export interface SessionRunResult {
108
118
  sessionId: string;
@@ -138,14 +148,14 @@ export interface SessionSummary {
138
148
  lastPrompt: string | null;
139
149
  updatedAt: string;
140
150
  status: SessionStatus;
141
- issue: TranscriptParseIssue | null;
151
+ issue: (TranscriptParseIssue | TranscriptCodecDiagnostic) | null;
142
152
  prNumber?: number;
143
153
  prUrl?: string;
144
154
  prRepository?: string;
145
155
  }
146
156
  export type SessionStatus = 'ready' | 'read-only' | 'corrupt';
147
157
  export interface SessionInspection extends SessionSummary {
148
- claudeVersion: string;
158
+ claudeVersion?: string;
149
159
  writeMode: 'read-only' | 'read-write';
150
160
  entryCount: number;
151
161
  byteLength: number;
@@ -218,6 +228,7 @@ export declare class ClaudeSessionService {
218
228
  private readonly sessionMemoryControllers;
219
229
  private resolvedSessionMemoryProvider;
220
230
  private readonly hookLifecycle;
231
+ private readonly leadOperations;
221
232
  private readonly fileChangeWatcher;
222
233
  private runtimeCwd;
223
234
  constructor(options: ClaudeSessionServiceOptions);
@@ -273,7 +284,7 @@ export declare class ClaudeSessionService {
273
284
  readEffectiveAgentColor(sessionId: string): Promise<AgentColorName | undefined>;
274
285
  export(sessionId: string): Promise<Buffer>;
275
286
  registerResumePath(requestedPath: string): Promise<SessionSummary>;
276
- transcript(sessionId: string, resumeSessionAt?: string): Promise<ClaudeDisplayTranscriptItem[]>;
287
+ transcript(sessionId: string, resumeSessionAt?: string): Promise<TranscriptDisplayItem[]>;
277
288
  interruption(sessionId: string): Promise<ClaudeInterruptionClassification>;
278
289
  metadata(sessionId: string): Promise<ClaudeSessionMetadata>;
279
290
  rename(sessionId: string, name: string): Promise<void>;
@@ -344,8 +355,14 @@ export declare class ClaudeSessionService {
344
355
  private rememberDurableMetadata;
345
356
  private assertSessionPersistence;
346
357
  private assertWritable;
358
+ private assertTurnWritable;
347
359
  private sessionStatus;
360
+ private nativeSessionStatus;
361
+ private nativeTranscriptWritesEnabled;
362
+ private assertNativeTranscriptOptions;
363
+ private claudeSessionSummary;
348
364
  private provider;
365
+ private assertNativeWriteTargetIsLegacy;
349
366
  model(): string | undefined;
350
367
  private providerForAgent;
351
368
  private resolveAgent;
@@ -361,7 +378,9 @@ export declare class ClaudeSessionService {
361
378
  private sessionMemoryProviderFactory;
362
379
  private toolCapabilities;
363
380
  private capabilityToolNames;
381
+ private teamRegistry;
364
382
  private append;
365
383
  private logicalTailUuid;
366
384
  }
385
+ export {};
367
386
  //# sourceMappingURL=session-service.d.ts.map