praxis-agent 0.34.0 → 0.35.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 (49) hide show
  1. package/README.md +4 -0
  2. package/dist/application/session-service.d.ts +0 -1
  3. package/dist/application/session-service.js +1619 -1617
  4. package/dist/application/subagent-service.js +27 -16
  5. package/dist/application/turn-lifecycle.d.ts +38 -0
  6. package/dist/application/turn-lifecycle.js +36 -0
  7. package/dist/cli/interactive.js +17 -7
  8. package/dist/cli/protocol.js +5 -2
  9. package/dist/cli/tui/claude-style.d.ts +5 -48
  10. package/dist/cli/tui/claude-style.js +19 -73
  11. package/dist/cli/tui/transcript-presentation.d.ts +89 -0
  12. package/dist/cli/tui/transcript-presentation.js +169 -0
  13. package/dist/cli/tui/transcript-viewport.d.ts +5 -34
  14. package/dist/cli/tui/transcript-viewport.js +639 -158
  15. package/dist/cli/tui/tui-view-model.d.ts +6 -2
  16. package/dist/cli/tui/tui-view-model.js +23 -6
  17. package/dist/compatibility/claude/context.d.ts +2 -2
  18. package/dist/compatibility/claude/context.js +2 -14
  19. package/dist/compatibility/claude/data-plane-adapter.d.ts +9 -0
  20. package/dist/compatibility/claude/data-plane-adapter.js +44 -0
  21. package/dist/compatibility/claude/paths.js +2 -2
  22. package/dist/compatibility/claude/shared-resources.d.ts +7 -38
  23. package/dist/compatibility/claude/transcript-codec.d.ts +21 -0
  24. package/dist/compatibility/claude/transcript-codec.js +512 -0
  25. package/dist/core/context.d.ts +25 -7
  26. package/dist/core/context.js +46 -0
  27. package/dist/core/prompt-composer.d.ts +8 -16
  28. package/dist/core/prompt-composer.js +65 -25
  29. package/dist/core/resources.d.ts +39 -0
  30. package/dist/core/resources.js +2 -0
  31. package/dist/core/runtime.d.ts +1 -1
  32. package/dist/core/session.d.ts +2 -0
  33. package/dist/core/session.js +5 -0
  34. package/dist/core/transcript-codec.d.ts +70 -0
  35. package/dist/core/transcript-codec.js +60 -0
  36. package/dist/core/transcript-event.d.ts +33 -0
  37. package/dist/core/transcript-event.js +198 -0
  38. package/dist/persistence/data-plane-adapter.d.ts +32 -0
  39. package/dist/persistence/data-plane-adapter.js +2 -0
  40. package/dist/persistence/data-plane.d.ts +4 -20
  41. package/dist/persistence/data-plane.js +10 -47
  42. package/dist/persistence/native-data-plane-adapter.d.ts +9 -0
  43. package/dist/persistence/native-data-plane-adapter.js +39 -0
  44. package/dist/persistence/native-resources.d.ts +4 -4
  45. package/dist/persistence/native-transcript-codec.d.ts +13 -0
  46. package/dist/persistence/native-transcript-codec.js +102 -0
  47. package/dist/tools/claude-user-message.d.ts +0 -1
  48. package/dist/tools/claude-user-message.js +0 -1
  49. package/package.json +6 -2
@@ -1,4 +1,5 @@
1
- import type { TranscriptItem } from './claude-style.js';
1
+ import type { TranscriptItem } from './transcript-presentation.js';
2
+ import { type TranscriptPresentationEntry } from './transcript-presentation.js';
2
3
  export type TuiRendererMode = 'default' | 'fullscreen';
3
4
  /**
4
5
  * Inputs for the pure TUI view projection. `history` is the live transcript
@@ -15,9 +16,12 @@ export interface TuiViewInput {
15
16
  rows: number | undefined;
16
17
  width: number;
17
18
  scrollOffset: number;
19
+ detailedTranscript: boolean;
18
20
  }
19
21
  export interface TuiViewModel {
20
- projectedHistory: readonly TranscriptItem[];
22
+ transcriptEntries: readonly TranscriptPresentationEntry[];
23
+ transcriptPageRows: number;
24
+ maxTranscriptScrollOffset: number;
21
25
  resumed: boolean;
22
26
  freshSession: boolean;
23
27
  hasConversationHistory: boolean;
@@ -1,4 +1,5 @@
1
- import { FULLSCREEN_TRANSCRIPT_RESERVED_ROWS, projectTranscriptTail, projectTranscriptWindow, } from './transcript-viewport.js';
1
+ import { projectTranscriptPresentation, } from './transcript-presentation.js';
2
+ import { FULLSCREEN_TRANSCRIPT_RESERVED_ROWS, projectTranscriptPresentationTail, projectTranscriptPresentationWindow, transcriptPresentationLineCount, } from './transcript-viewport.js';
2
3
  /**
3
4
  * Pure, deterministic TUI projection. It classifies the session identity
4
5
  * (fresh/resumed/started) and projects the rendered transcript exactly as the
@@ -27,12 +28,28 @@ export function projectTuiView(input) {
27
28
  // viewport, leaving the composer/status chrome intact and keeping the active
28
29
  // stream visible. Classic and screen-reader modes always render the full
29
30
  // history exactly as before.
30
- const projectedHistory = input.fixedViewport && !input.screenReader
31
+ const mode = input.screenReader
32
+ ? 'screen-reader'
33
+ : input.detailedTranscript
34
+ ? 'audit'
35
+ : 'normal';
36
+ const fullEntries = projectTranscriptPresentation(input.history, mode);
37
+ const transcriptPageRows = Math.max(2, (input.rows ?? 0) - FULLSCREEN_TRANSCRIPT_RESERVED_ROWS);
38
+ const maxTranscriptScrollOffset = Math.max(0, transcriptPresentationLineCount(fullEntries, input.width, mode) -
39
+ transcriptPageRows);
40
+ const transcriptEntries = input.fixedViewport && !input.screenReader
31
41
  ? input.scrollOffset > 0
32
- ? projectTranscriptWindow(input.history, Math.max(1, (input.rows ?? 0) - FULLSCREEN_TRANSCRIPT_RESERVED_ROWS), input.width, input.scrollOffset)
33
- : projectTranscriptTail(input.history, Math.max(1, (input.rows ?? 0) - FULLSCREEN_TRANSCRIPT_RESERVED_ROWS), input.width)
34
- : input.history;
35
- return { projectedHistory, resumed, freshSession, hasConversationHistory };
42
+ ? projectTranscriptPresentationWindow(fullEntries, transcriptPageRows, input.width, input.scrollOffset, mode)
43
+ : projectTranscriptPresentationTail(fullEntries, transcriptPageRows, input.width, mode)
44
+ : fullEntries;
45
+ return {
46
+ transcriptEntries,
47
+ transcriptPageRows,
48
+ maxTranscriptScrollOffset,
49
+ resumed,
50
+ freshSession,
51
+ hasConversationHistory,
52
+ };
36
53
  }
37
54
  /**
38
55
  * Resolves the renderer for an interactive session. Fullscreen is the default
@@ -1,4 +1,4 @@
1
- import type { AssembledContext, ContextAssembler, ContextAssemblyOptions, ContextInvalidationOptions } from '../../core/context.js';
1
+ import type { ContextAssembler, ContextAssemblyOptions, ContextSnapshot, ContextInvalidationOptions } from '../../core/context.js';
2
2
  import { type ClaudeDynamicContextSections } from './dynamic-context.js';
3
3
  import type { ClaudeContextResources, ClaudeConditionalRule, ClaudeTextResource } from './shared-resources.js';
4
4
  export interface ClaudeContextAssemblerOptions {
@@ -32,7 +32,7 @@ export declare class ClaudeContextAssembler implements ContextAssembler {
32
32
  private readonly composer;
33
33
  private readonly snapshots;
34
34
  constructor(options: ClaudeContextAssemblerOptions);
35
- assemble(options?: ContextAssemblyOptions): Promise<AssembledContext>;
35
+ assemble(options?: ContextAssemblyOptions): Promise<ContextSnapshot>;
36
36
  invalidate(options: ContextInvalidationOptions): void;
37
37
  private snapshot;
38
38
  private loadResources;
@@ -135,12 +135,6 @@ ${sections.join('\n\n')}`,
135
135
  });
136
136
  }
137
137
  }
138
- for (const section of options.additionalSections ?? []) {
139
- const target = section.stability === 'volatile' || section.placement === 'first-user'
140
- ? tailSections
141
- : sessionSections;
142
- target.push(section);
143
- }
144
138
  const composition = this.composer.compose({
145
139
  mode,
146
140
  ...(options.baseSystemPrompt !== undefined
@@ -153,15 +147,9 @@ ${sections.join('\n\n')}`,
153
147
  : {}),
154
148
  sessionSections,
155
149
  tailSections,
150
+ ...(options.turn === undefined ? {} : { turn: options.turn }),
156
151
  });
157
- return {
158
- systemMessages: composition.systemMessages,
159
- promptSections: composition.sections,
160
- stableSystemSectionCount: composition.stableSystemSectionCount,
161
- ...(composition.firstUserMessageContext
162
- ? { firstUserMessageContext: composition.firstUserMessageContext }
163
- : {}),
164
- };
152
+ return composition;
165
153
  }
166
154
  invalidate(options) {
167
155
  for (const [key, snapshot] of this.snapshots) {
@@ -0,0 +1,9 @@
1
+ import type { DataPlaneAdapter, DataPlaneAdapterOptions, DataPlanePaths, DataPlaneRootOptions, ScheduledTaskFileOptions } from '../../persistence/data-plane-adapter.js';
2
+ export declare class ClaudeDataPlaneAdapter implements DataPlaneAdapter {
3
+ readonly dataPlane: "claude";
4
+ resolveRoot(options: DataPlaneRootOptions): string;
5
+ resolvePaths(options: DataPlaneAdapterOptions): DataPlanePaths;
6
+ resolveScheduledTaskFile(options: ScheduledTaskFileOptions): string;
7
+ }
8
+ export declare const claudeDataPlaneAdapter: ClaudeDataPlaneAdapter;
9
+ //# sourceMappingURL=data-plane-adapter.d.ts.map
@@ -0,0 +1,44 @@
1
+ import { homedir } from 'node:os';
2
+ import { resolve } from 'node:path';
3
+ import { isSessionId } from '../../core/session.js';
4
+ import { resolveClaudePaths, resolveClaudeScheduledTaskFile, sanitizeClaudeProjectPath, } from './paths.js';
5
+ export class ClaudeDataPlaneAdapter {
6
+ dataPlane = 'claude';
7
+ resolveRoot(options) {
8
+ const environment = options.environment ?? process.env;
9
+ if (options.root?.trim())
10
+ return resolve(options.root);
11
+ const configuredRoot = environment.CLAUDE_CONFIG_DIR;
12
+ return resolve(configuredRoot?.trim()
13
+ ? configuredRoot
14
+ : resolve(options.homeDirectory ?? homedir(), '.claude'));
15
+ }
16
+ resolvePaths(options) {
17
+ if (!isSessionId(options.sessionId)) {
18
+ throw new Error(`Invalid session ID: ${options.sessionId}`);
19
+ }
20
+ const root = this.resolveRoot(options);
21
+ const paths = resolveClaudePaths({
22
+ cwd: options.cwd,
23
+ sessionId: options.sessionId,
24
+ configDir: root,
25
+ });
26
+ const projectKey = sanitizeClaudeProjectPath(options.cwd);
27
+ const stateRoot = paths.praxisRoot;
28
+ return {
29
+ dataPlane: 'claude',
30
+ root: paths.configRoot,
31
+ projectRoot: paths.projectRoot,
32
+ sessionFile: paths.sessionFile,
33
+ taskRoot: paths.taskRoot,
34
+ stateRoot,
35
+ praxisRoot: stateRoot,
36
+ memoryRoot: resolve(root, 'projects', projectKey, 'memory'),
37
+ };
38
+ }
39
+ resolveScheduledTaskFile(options) {
40
+ return resolveClaudeScheduledTaskFile(options.cwd);
41
+ }
42
+ }
43
+ export const claudeDataPlaneAdapter = new ClaudeDataPlaneAdapter();
44
+ //# sourceMappingURL=data-plane-adapter.js.map
@@ -1,12 +1,12 @@
1
1
  import { lstat, readdir } from 'node:fs/promises';
2
2
  import { homedir } from 'node:os';
3
3
  import { extname, resolve } from 'node:path';
4
+ import { isSessionId } from '../../core/session.js';
4
5
  import { sanitizeProjectPath } from '../../platform/project-path-key.js';
5
6
  import { getDataOwnership } from './ownership.js';
6
7
  const MAX_SANITIZED_LENGTH = 200;
7
- const SESSION_ID_PATTERN = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
8
8
  export function isClaudeSessionId(value) {
9
- return SESSION_ID_PATTERN.test(value);
9
+ return isSessionId(value);
10
10
  }
11
11
  export function sanitizeClaudeProjectPath(path) {
12
12
  return sanitizeProjectPath(path);
@@ -1,41 +1,10 @@
1
- export type ClaudeResourceScope = 'local' | 'project' | 'user';
2
- export interface ClaudeTextResource {
3
- path: string;
4
- scope: ClaudeResourceScope;
5
- content: string;
6
- importedFrom?: string;
7
- importRoot?: string;
8
- }
9
- export interface ClaudeJsonResource {
10
- path: string;
11
- scope: ClaudeResourceScope;
12
- value: unknown;
13
- plugin?: true;
14
- pluginName?: string;
15
- pluginSource?: string;
16
- environment?: Readonly<Record<string, string>>;
17
- sensitiveValues?: readonly string[];
18
- }
19
- export interface ClaudeContextResources {
20
- instructions: ClaudeTextResource[];
21
- conditionalRules: ClaudeConditionalRule[];
22
- memoryIndex: ClaudeTextResource | null;
23
- }
24
- export interface ClaudeConditionalRule extends ClaudeTextResource {
25
- baseDirectory: string;
26
- content: string;
27
- globs: string[];
28
- rawContent: string;
29
- }
30
- export interface ClaudeSharedResources {
31
- instructions: ClaudeTextResource[];
32
- memory: ClaudeTextResource[];
33
- skills: ClaudeTextResource[];
34
- commands: ClaudeTextResource[];
35
- agents: ClaudeTextResource[];
36
- settings: ClaudeJsonResource[];
37
- mcp: ClaudeJsonResource[];
38
- }
1
+ import type { ConditionalRule, ContextResources, JsonResource, ResourceScope, SharedResources, TextResource } from '../../core/resources.js';
2
+ export type ClaudeResourceScope = ResourceScope;
3
+ export type ClaudeTextResource = TextResource;
4
+ export type ClaudeJsonResource = JsonResource;
5
+ export type ClaudeContextResources = ContextResources;
6
+ export type ClaudeConditionalRule = ConditionalRule;
7
+ export type ClaudeSharedResources = SharedResources;
39
8
  export interface LoadClaudeSharedResourcesOptions {
40
9
  configRoot: string;
41
10
  cwd: string;
@@ -0,0 +1,21 @@
1
+ import { type TranscriptEvent } from '../../core/transcript-event.js';
2
+ import { type OpaquePreservationToken, type TranscriptCodec, type TranscriptDocumentResult, type TranscriptEncodeResult, type TranscriptLineResult } from '../../core/transcript-codec.js';
3
+ export interface ClaudeTranscriptCodecOptions {
4
+ version: string;
5
+ cwd: string;
6
+ gitBranch?: string | null;
7
+ entrypoint?: string;
8
+ }
9
+ export declare class ClaudeTranscriptCodec implements TranscriptCodec {
10
+ private readonly options;
11
+ readonly id = "claude";
12
+ readonly version: string;
13
+ readonly writeMode: 'read-only' | 'read-write';
14
+ private readonly adapter;
15
+ constructor(options: ClaudeTranscriptCodecOptions);
16
+ decodeLine(line: string, lineNumber?: number, byteOffset?: number): TranscriptLineResult;
17
+ encodeLine(event: TranscriptEvent, preservation?: OpaquePreservationToken): TranscriptEncodeResult;
18
+ decodeDocument(source: string | Uint8Array): TranscriptDocumentResult;
19
+ }
20
+ export declare function createClaudeTranscriptCodec(options: ClaudeTranscriptCodecOptions): ClaudeTranscriptCodec;
21
+ //# sourceMappingURL=transcript-codec.d.ts.map