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,196 @@
1
+ import { createHash } from 'node:crypto';
2
+ import { Buffer } from 'node:buffer';
3
+ import { parseTeamMailboxPayload, } from '../core/team-mailbox.js';
4
+ import { parseTeamId } from '../core/team-ownership.js';
5
+ import { NativeTeamMailbox, } from '../persistence/native-team-mailbox.js';
6
+ const DEFAULT_MAX_BYTES = 64 * 1024;
7
+ const DEFAULT_MAX_MESSAGES = 32;
8
+ function participant(value) {
9
+ if (typeof value !== 'string' || value.trim() === '')
10
+ throw new Error('Invalid Team mailbox participant');
11
+ return value;
12
+ }
13
+ function operationIdentity(value) {
14
+ if (typeof value !== 'string' ||
15
+ value.trim() === '' ||
16
+ value !== value.trim() ||
17
+ value.length > 300 ||
18
+ value.includes('\r') ||
19
+ value.includes('\n'))
20
+ throw new Error('Invalid Team mailbox operation ID');
21
+ return value;
22
+ }
23
+ export function teamMailboxMessageId(teamId, sender, operationId) {
24
+ const values = [
25
+ parseTeamId(teamId),
26
+ participant(sender),
27
+ operationIdentity(operationId),
28
+ ];
29
+ const hash = createHash('sha256');
30
+ for (const value of values) {
31
+ const bytes = Buffer.from(value, 'utf8');
32
+ hash.update(Buffer.from(String(bytes.length) + ':', 'ascii'));
33
+ hash.update(bytes);
34
+ }
35
+ return hash.digest('hex');
36
+ }
37
+ function render(message) {
38
+ return `<team-mailbox-message>\n${JSON.stringify(message)}\n</team-mailbox-message>`;
39
+ }
40
+ function assertBound(value, label) {
41
+ if (!Number.isSafeInteger(value) || value <= 0)
42
+ throw new Error(`Invalid ${label}`);
43
+ return value;
44
+ }
45
+ export class TeamMailboxService {
46
+ options;
47
+ store;
48
+ participants;
49
+ participantSet;
50
+ constructor(options) {
51
+ this.options = options;
52
+ if (!Array.isArray(options.participants) ||
53
+ options.participants.length === 0)
54
+ throw new Error('Invalid Team mailbox participants');
55
+ this.participants = Object.freeze(options.participants.map(participant));
56
+ if (new Set(this.participants).size !== this.participants.length ||
57
+ !this.participants.includes('lead'))
58
+ throw new Error('Invalid Team mailbox roster');
59
+ this.participantSet = new Set(this.participants);
60
+ if (options.store) {
61
+ this.store = options.store;
62
+ }
63
+ else {
64
+ if (!options.nativeRoot || !options.projectIdentity)
65
+ throw new Error('Native Team mailbox root and project identity are required');
66
+ this.store = NativeTeamMailbox.open({
67
+ nativeRoot: options.nativeRoot,
68
+ projectIdentity: options.projectIdentity,
69
+ teamId: options.teamId,
70
+ participants: this.participants,
71
+ ...(options.retention ? { retention: options.retention } : {}),
72
+ });
73
+ }
74
+ }
75
+ endpoint(sender) {
76
+ this.assertParticipant(sender);
77
+ return new TeamMailboxEndpoint(this, sender);
78
+ }
79
+ async send(input, sender) {
80
+ this.assertParticipant(sender);
81
+ const recipients = this.recipients(input.to, sender);
82
+ const result = await this.store.append({
83
+ messageId: input.messageId,
84
+ sender,
85
+ recipients,
86
+ payload: parseTeamMailboxPayload(input.payload),
87
+ ...(input.createdAt === undefined ? {} : { createdAt: input.createdAt }),
88
+ });
89
+ if (this.options.wake) {
90
+ try {
91
+ await this.options.wake({
92
+ teamId: result.message.teamId,
93
+ messageId: result.message.messageId,
94
+ sequence: result.message.sequence,
95
+ recipients: result.message.recipients,
96
+ });
97
+ }
98
+ catch (error) {
99
+ try {
100
+ this.options.warn?.(`Team mailbox wake failed: ${error instanceof Error ? error.message : String(error)}`);
101
+ }
102
+ catch {
103
+ // Advisory reporting must not change a durably persisted send result.
104
+ }
105
+ }
106
+ }
107
+ return result.message;
108
+ }
109
+ async project(sender, bounds = {}) {
110
+ this.assertParticipant(sender);
111
+ const maxBytes = bounds.maxBytes === undefined
112
+ ? DEFAULT_MAX_BYTES
113
+ : assertBound(bounds.maxBytes, 'mailbox projection maxBytes');
114
+ const maxMessages = bounds.maxMessages === undefined
115
+ ? DEFAULT_MAX_MESSAGES
116
+ : assertBound(bounds.maxMessages, 'mailbox projection maxMessages');
117
+ const read = await this.store.read(sender, { maxMessages });
118
+ if (read.messages.length === 0)
119
+ return null;
120
+ const messages = [];
121
+ let bytes = 0;
122
+ for (const message of read.messages) {
123
+ const text = render(message);
124
+ const size = Buffer.byteLength(text, 'utf8');
125
+ if (messages.length === 0 && size > maxBytes)
126
+ throw new Error('First Team mailbox message exceeds projection budget');
127
+ if (messages.length >= maxMessages || bytes + size > maxBytes)
128
+ break;
129
+ messages.push(text);
130
+ bytes += size;
131
+ }
132
+ if (messages.length === 0)
133
+ return null;
134
+ const selected = read.messages.slice(0, messages.length);
135
+ const last = selected[selected.length - 1];
136
+ if (!last)
137
+ throw new Error('Team mailbox projection selected no messages');
138
+ const proof = {
139
+ participant: sender,
140
+ expectedCursor: read.expectedCursor,
141
+ throughSequence: last.sequence,
142
+ messageIds: selected.map((message) => message.messageId),
143
+ };
144
+ const id = `${this.options.teamId}:${sender}:${proof.expectedCursor}-${proof.throughSequence}`;
145
+ let acknowledged = false;
146
+ return {
147
+ id,
148
+ messages: Object.freeze(messages),
149
+ acknowledge: async () => {
150
+ if (acknowledged)
151
+ return;
152
+ await this.store.acknowledge(proof);
153
+ acknowledged = true;
154
+ },
155
+ };
156
+ }
157
+ recipients(to, sender) {
158
+ if (to === 'broadcast') {
159
+ return Object.freeze([...this.participants].filter((name) => name !== sender).sort());
160
+ }
161
+ const values = typeof to === 'string' ? [to] : [...to];
162
+ if (values.length === 0)
163
+ throw new Error('Team mailbox delivery requires a recipient');
164
+ const result = [];
165
+ for (const value of values) {
166
+ this.assertParticipant(value);
167
+ if (value === sender)
168
+ throw new Error('Team mailbox sender cannot address itself');
169
+ if (!result.includes(value))
170
+ result.push(value);
171
+ }
172
+ if (result.length === 0)
173
+ throw new Error('Team mailbox delivery requires a recipient');
174
+ return Object.freeze(result);
175
+ }
176
+ assertParticipant(value) {
177
+ const name = participant(value);
178
+ if (!this.participantSet.has(name))
179
+ throw new Error(`Unknown Team mailbox participant: ${name}`);
180
+ }
181
+ }
182
+ export class TeamMailboxEndpoint {
183
+ service;
184
+ participant;
185
+ constructor(service, participant) {
186
+ this.service = service;
187
+ this.participant = participant;
188
+ }
189
+ send(input) {
190
+ return this.service.send(input, this.participant);
191
+ }
192
+ project(bounds) {
193
+ return this.service.project(this.participant, bounds);
194
+ }
195
+ }
196
+ //# sourceMappingURL=team-mailbox.js.map
@@ -0,0 +1,113 @@
1
+ import type { PermissionResolver, ToolRegistry } from '../core/runtime.js';
2
+ import { type TeamMember, type TeamSnapshot, type TeamTask, type TeamLeadPolicy, type TeamExecutionPolicy, type TeamCommitPolicy, DEFAULT_TEAM_BUDGETS } from '../core/team-ownership.js';
3
+ import { type NativeTeamClaim } from '../persistence/native-team-store.js';
4
+ import { type TeamWorkspaceProvider } from './team-workspace.js';
5
+ import { TeamMailboxService, type TeamMailboxEndpoint } from './team-mailbox.js';
6
+ export interface TeamCreateTaskInput extends Omit<TeamTask, 'execution' | 'usage'> {
7
+ }
8
+ export interface TeamCreateInput {
9
+ readonly teamId: string;
10
+ readonly name: string;
11
+ readonly leadSessionId: string;
12
+ readonly roster: readonly TeamMember[];
13
+ readonly tasks: readonly TeamCreateTaskInput[];
14
+ readonly leadPolicy?: TeamLeadPolicy;
15
+ readonly executionPolicy?: TeamExecutionPolicy;
16
+ readonly commitPolicy?: TeamCommitPolicy;
17
+ readonly budgets?: Partial<typeof DEFAULT_TEAM_BUDGETS>;
18
+ }
19
+ export interface TeamAgentProgress {
20
+ readonly generation: number;
21
+ readonly totalTokens: number;
22
+ readonly durationMs: number;
23
+ }
24
+ export interface TeamAgentRunResult {
25
+ readonly status: 'completed' | 'failed' | 'orphaned';
26
+ readonly totalTokens: number;
27
+ readonly durationMs: number;
28
+ }
29
+ export interface TeamAgentRuntime {
30
+ run(input: {
31
+ readonly teamId: string;
32
+ readonly task: TeamTask;
33
+ readonly member: TeamMember;
34
+ readonly generation: number;
35
+ readonly cwd: string;
36
+ readonly branch: string | null;
37
+ readonly tools: ToolRegistry;
38
+ readonly permissions: PermissionResolver;
39
+ readonly signal: AbortSignal;
40
+ readonly mailbox: TeamMailboxEndpoint;
41
+ readonly reportProgress: (progress: TeamAgentProgress) => void;
42
+ }): Promise<TeamAgentRunResult>;
43
+ }
44
+ export interface LocalTeamManagerOptions {
45
+ readonly nativeRoot: string;
46
+ readonly cwd: string;
47
+ readonly maxConcurrent: number;
48
+ readonly baseTools: ToolRegistry;
49
+ readonly permissions: PermissionResolver;
50
+ readonly runtime: TeamAgentRuntime;
51
+ readonly workspace?: TeamWorkspaceProvider;
52
+ }
53
+ export declare class LocalTeamManager {
54
+ private readonly store;
55
+ private readonly options;
56
+ private readonly workspace;
57
+ private constructor();
58
+ static open(options: LocalTeamManagerOptions): Promise<LocalTeamManager>;
59
+ create(input: TeamCreateInput): Promise<LocalTeam>;
60
+ resume(input: {
61
+ teamId: string;
62
+ leadSessionId: string;
63
+ }): Promise<LocalTeam>;
64
+ list(): Promise<readonly TeamSnapshot[]>;
65
+ }
66
+ export declare class LocalTeam {
67
+ private readonly options;
68
+ private readonly workspace;
69
+ private readonly claim;
70
+ private readonly mailbox;
71
+ private mutation;
72
+ private readonly active;
73
+ private admissionOpen;
74
+ private stopping;
75
+ private detaching;
76
+ private detachedSnapshot;
77
+ private finalSnapshot;
78
+ private pumpFailure;
79
+ private readonly indeterminate;
80
+ private readonly progressWrites;
81
+ private readonly stopStarted;
82
+ private readonly resolveStopStarted;
83
+ private deadlineTimer;
84
+ private progressOpen;
85
+ constructor(options: LocalTeamManagerOptions, workspace: TeamWorkspaceProvider, claim: NativeTeamClaim, mailbox: TeamMailboxService);
86
+ mailboxEndpoint(participant: string): TeamMailboxEndpoint;
87
+ initialize(resume: boolean): Promise<void>;
88
+ snapshot(): Promise<TeamSnapshot>;
89
+ waitForIdle(): Promise<TeamSnapshot>;
90
+ accept(taskId: string, generation?: number, decision?: 'accepted' | 'rejected'): Promise<TeamSnapshot>;
91
+ stop(options?: {
92
+ drainMs?: number;
93
+ }): Promise<TeamSnapshot>;
94
+ detach(): Promise<TeamSnapshot>;
95
+ private detachInternal;
96
+ private stopWithBudget;
97
+ private stopInternal;
98
+ private clearDeadlineTimer;
99
+ private enqueue;
100
+ private reconcileOrphans;
101
+ private pump;
102
+ private pumpMutation;
103
+ private launch;
104
+ private complete;
105
+ private queueProgress;
106
+ private persistProgress;
107
+ private initializeDeadline;
108
+ private exhaustDuration;
109
+ private beginBudgetShutdown;
110
+ private markCancelling;
111
+ private finishStopping;
112
+ }
113
+ //# sourceMappingURL=team-manager.d.ts.map