pi-sessions 0.10.0 → 0.11.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 (33) hide show
  1. package/README.md +25 -20
  2. package/dist/session-messaging/broker/client-frame.js +62 -0
  3. package/dist/session-messaging/broker/process.js +2 -2
  4. package/dist/shared/session-broker/framing.js +4 -3
  5. package/extensions/pi-sessions.ts +14 -1
  6. package/extensions/session-auto-title/generate.ts +56 -66
  7. package/extensions/session-auto-title/install.ts +2 -0
  8. package/extensions/session-auto-title/runs.ts +50 -0
  9. package/extensions/session-handoff/kickoff.ts +4 -3
  10. package/extensions/session-messaging/broker/client-frame.ts +113 -0
  11. package/extensions/session-messaging/broker/process.ts +12 -21
  12. package/extensions/session-messaging/pi/reachable-contract.ts +59 -0
  13. package/extensions/session-messaging/pi/reachable-presenter.ts +49 -0
  14. package/extensions/session-messaging/pi/reachable-tool.ts +190 -0
  15. package/extensions/session-messaging/pi/reachable-view-model.ts +59 -0
  16. package/extensions/session-messaging/pi/renderer.ts +1 -1
  17. package/extensions/session-messaging/pi/tools.ts +8 -8
  18. package/extensions/session-search/hooks.ts +45 -52
  19. package/extensions/session-search/install.ts +3 -158
  20. package/extensions/session-search/reindex.ts +3 -3
  21. package/extensions/session-search/renderer.ts +1 -32
  22. package/extensions/session-search/tool-contract.ts +1 -21
  23. package/extensions/shared/model-runtime.ts +8 -1
  24. package/extensions/shared/session-broker/client.ts +3 -4
  25. package/extensions/shared/session-broker/framing.ts +6 -7
  26. package/extensions/shared/session-index/lineage.ts +6 -2
  27. package/extensions/shared/session-index/sqlite.ts +44 -17
  28. package/extensions/shared/settings.ts +13 -2
  29. package/extensions/shared/tmux.ts +22 -0
  30. package/extensions/subagents/report-message-renderer.ts +2 -2
  31. package/package.json +17 -29
  32. package/dist/shared/session-broker/protocol.js +0 -163
  33. package/dist/shared/typebox.js +0 -36
@@ -5,7 +5,7 @@ import { SUBAGENT_REPORT_MESSAGE_SCHEMA } from "./ledger.ts";
5
5
  import { presentSubagentReportMessage } from "./report-message-presenter.ts";
6
6
  import { buildSubagentReportMessageView } from "./report-message-view-model.ts";
7
7
 
8
- export const renderSubagentReportMessage: MessageRenderer = (message, _options, theme) => {
8
+ export const renderSubagentReportMessage: MessageRenderer = (message, options, theme) => {
9
9
  const details = safeParseTypeBoxValue(SUBAGENT_REPORT_MESSAGE_SCHEMA, message.details);
10
10
  if (!details) {
11
11
  return undefined;
@@ -15,7 +15,7 @@ export const renderSubagentReportMessage: MessageRenderer = (message, _options,
15
15
  return undefined;
16
16
  }
17
17
 
18
- const box = new Box(1, 1, (text) => theme.bg("customMessageBg", text));
18
+ const box = new Box(options.outputPad, 1, (text) => theme.bg("customMessageBg", text));
19
19
  box.addChild(new Text(presentSubagentReportMessage(report, theme), 0, 0));
20
20
  return box;
21
21
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pi-sessions",
3
- "version": "0.10.0",
3
+ "version": "0.11.0",
4
4
  "type": "module",
5
5
  "description": "Pi session search, ask, handoff, messaging, auto-titling, and indexing tools",
6
6
  "license": "MIT",
@@ -29,41 +29,29 @@
29
29
  ]
30
30
  },
31
31
  "scripts": {
32
- "build:broker": "tsc --project tsconfig.broker.json",
33
- "lint": "biome check .",
34
- "format": "biome format --write .",
35
- "typecheck": "tsc --noEmit",
36
- "pretest": "npm run build:broker",
37
- "test": "vitest run",
38
- "check": "biome check . && tsc --noEmit && npm test",
39
- "prepare": "npm run build:broker && npm run prepare:husky",
40
- "prepare:husky": "husky || true"
41
- },
42
- "dependencies": {
43
- "typebox": "^1.1.38"
32
+ "build:broker": "mise run build:broker",
33
+ "lint": "mise run lint",
34
+ "format": "mise run format",
35
+ "typecheck": "mise run typecheck",
36
+ "test": "mise run test",
37
+ "check": "mise run check"
44
38
  },
45
39
  "devDependencies": {
46
40
  "@biomejs/biome": "^2.4.14",
47
- "@earendil-works/pi-agent-core": "^0.80.10",
48
- "@earendil-works/pi-ai": "^0.80.10",
49
- "@earendil-works/pi-coding-agent": "^0.80.10",
50
- "@earendil-works/pi-tui": "^0.80.10",
41
+ "@earendil-works/pi-agent-core": "^0.82.1",
42
+ "@earendil-works/pi-ai": "^0.82.1",
43
+ "@earendil-works/pi-coding-agent": "^0.82.1",
44
+ "@earendil-works/pi-tui": "^0.82.1",
51
45
  "@types/node": "^25.6.2",
52
- "husky": "^9.1.7",
53
- "lint-staged": "^17.0.3",
46
+ "strip-ansi": "^7.2.0",
47
+ "typebox": "^1.1.38",
54
48
  "typescript": "^6.0.3",
55
49
  "vitest": "^4.1.5"
56
50
  },
57
51
  "peerDependencies": {
58
- "@earendil-works/pi-agent-core": ">=0.80.10",
59
- "@earendil-works/pi-ai": ">=0.80.10",
60
- "@earendil-works/pi-coding-agent": ">=0.80.10",
61
- "@earendil-works/pi-tui": ">=0.80.10"
62
- },
63
- "lint-staged": {
64
- "*.{js,cjs,mjs,jsx,ts,tsx,json,jsonc}": "biome check --write --no-errors-on-unmatched"
65
- },
66
- "optionalDependencies": {
67
- "better-sqlite3": "^12.9.0"
52
+ "@earendil-works/pi-agent-core": ">=0.82.1",
53
+ "@earendil-works/pi-ai": ">=0.82.1",
54
+ "@earendil-works/pi-coding-agent": ">=0.82.1",
55
+ "@earendil-works/pi-tui": ">=0.82.1"
68
56
  }
69
57
  }
@@ -1,163 +0,0 @@
1
- import { Type } from "typebox";
2
- export const TASK_REPORT_REFERENCE_SCHEMA = Type.Object({
3
- reference: Type.String({
4
- description: "A precise reference such as a file path and line range, symbol name, command, URL, session id, or external artifact.",
5
- }),
6
- description: Type.Optional(Type.String({
7
- description: "Why this reference matters or what evidence the parent should take from it.",
8
- })),
9
- });
10
- export const TASK_REPORT_SCHEMA = Type.Object({
11
- status: Type.Union([
12
- Type.Literal("done", {
13
- description: "The delegated task or requested follow-up is complete.",
14
- }),
15
- Type.Literal("blocked", {
16
- description: "The task cannot continue without a specific decision, clarification, permission, dependency, or other action outside the scope of the task.",
17
- }),
18
- Type.Literal("incomplete", {
19
- description: "Useful work was performed, but the requested result could not be completed and it's uncertain what should be done to reach completion.",
20
- }),
21
- ], { description: "The subagent's assessment of the task at the end of this turn." }),
22
- summary: Type.String({
23
- description: "A concise, 3-4 sentence self-contained account of the outcome and its most important evidence.",
24
- }),
25
- details: Type.Optional(Type.String({
26
- description: "Optional supporting context such as reasoning, implementation notes, validation performed, limitations, unexpected behavior or roadblocks, or failed approaches.",
27
- })),
28
- references: Type.Optional(Type.Array(TASK_REPORT_REFERENCE_SCHEMA, {
29
- description: "Supporting material for the report.",
30
- })),
31
- nextSteps: Type.Optional(Type.Array(Type.String(), {
32
- description: "Optional concrete actions that would extend or build on the state of the work. If blocked or incomplete, call out specifically what is causing the early return.",
33
- })),
34
- });
35
- const OUTBOUND_MESSAGE_ENVELOPE_SCHEMA = Type.Object({
36
- kind: Type.Literal("message"),
37
- messageId: Type.String(),
38
- body: Type.String(),
39
- requestResponse: Type.Optional(Type.Boolean()),
40
- sentAt: Type.String(),
41
- sourceToolCallId: Type.Optional(Type.String()),
42
- });
43
- const OUTBOUND_CANCEL_ENVELOPE_SCHEMA = Type.Object({
44
- kind: Type.Literal("cancel"),
45
- cancelId: Type.String(),
46
- sentAt: Type.String(),
47
- });
48
- const OUTBOUND_SUBAGENT_REPORT_ENVELOPE_SCHEMA = Type.Intersect([
49
- Type.Object({
50
- kind: Type.Literal("subagent_report"),
51
- reportId: Type.String(),
52
- sentAt: Type.String(),
53
- }),
54
- TASK_REPORT_SCHEMA,
55
- ]);
56
- export const OUTBOUND_SESSION_ENVELOPE_SCHEMA = Type.Union([
57
- OUTBOUND_MESSAGE_ENVELOPE_SCHEMA,
58
- OUTBOUND_CANCEL_ENVELOPE_SCHEMA,
59
- OUTBOUND_SUBAGENT_REPORT_ENVELOPE_SCHEMA,
60
- ]);
61
- export const SESSION_MESSAGE_ENVELOPE_SCHEMA = Type.Object({
62
- kind: Type.Literal("message"),
63
- messageId: Type.String(),
64
- source: Type.String(),
65
- target: Type.String(),
66
- body: Type.String(),
67
- requestResponse: Type.Optional(Type.Boolean()),
68
- sentAt: Type.String(),
69
- sourceToolCallId: Type.Optional(Type.String()),
70
- });
71
- export const SESSION_CANCEL_ENVELOPE_SCHEMA = Type.Object({
72
- kind: Type.Literal("cancel"),
73
- cancelId: Type.String(),
74
- source: Type.String(),
75
- target: Type.String(),
76
- sentAt: Type.String(),
77
- });
78
- export const SESSION_SUBAGENT_REPORT_ENVELOPE_SCHEMA = Type.Intersect([
79
- Type.Object({
80
- kind: Type.Literal("subagent_report"),
81
- reportId: Type.String(),
82
- source: Type.String(),
83
- target: Type.String(),
84
- sentAt: Type.String(),
85
- }),
86
- TASK_REPORT_SCHEMA,
87
- ]);
88
- export const SESSION_ENVELOPE_SCHEMA = Type.Union([
89
- SESSION_MESSAGE_ENVELOPE_SCHEMA,
90
- SESSION_CANCEL_ENVELOPE_SCHEMA,
91
- SESSION_SUBAGENT_REPORT_ENVELOPE_SCHEMA,
92
- ]);
93
- const REGISTER_CLIENT_FRAME_SCHEMA = Type.Object({
94
- type: Type.Literal("register"),
95
- sessionId: Type.String(),
96
- });
97
- const UNREGISTER_CLIENT_FRAME_SCHEMA = Type.Object({
98
- type: Type.Literal("unregister"),
99
- });
100
- const LIST_CLIENT_FRAME_SCHEMA = Type.Object({
101
- type: Type.Literal("list"),
102
- requestId: Type.String(),
103
- });
104
- const SEND_CLIENT_FRAME_SCHEMA = Type.Object({
105
- type: Type.Literal("send"),
106
- requestId: Type.String(),
107
- target: Type.String(),
108
- envelope: OUTBOUND_SESSION_ENVELOPE_SCHEMA,
109
- });
110
- const INCOMING_ACK_CLIENT_FRAME_SCHEMA = Type.Object({
111
- type: Type.Literal("incoming_ack"),
112
- requestId: Type.String(),
113
- delivered: Type.Boolean(),
114
- error: Type.Optional(Type.String()),
115
- });
116
- const REGISTERED_BROKER_FRAME_SCHEMA = Type.Object({
117
- type: Type.Literal("registered"),
118
- sessionId: Type.String(),
119
- });
120
- const REGISTER_FAILED_BROKER_FRAME_SCHEMA = Type.Object({
121
- type: Type.Literal("register_failed"),
122
- reason: Type.String(),
123
- });
124
- const SESSIONS_BROKER_FRAME_SCHEMA = Type.Object({
125
- type: Type.Literal("sessions"),
126
- requestId: Type.String(),
127
- sessionIds: Type.Array(Type.String()),
128
- });
129
- const INCOMING_BROKER_FRAME_SCHEMA = Type.Object({
130
- type: Type.Literal("incoming"),
131
- requestId: Type.String(),
132
- envelope: SESSION_ENVELOPE_SCHEMA,
133
- });
134
- export const SESSION_ENVELOPE_SEND_FAILURE_REASON_SCHEMA = Type.Union([
135
- Type.Literal("no_session"),
136
- Type.Literal("disconnected"),
137
- ]);
138
- const SEND_RESULT_BROKER_FRAME_SCHEMA = Type.Object({
139
- type: Type.Literal("send_result"),
140
- requestId: Type.String(),
141
- delivered: Type.Boolean(),
142
- reason: Type.Optional(SESSION_ENVELOPE_SEND_FAILURE_REASON_SCHEMA),
143
- error: Type.Optional(Type.String()),
144
- });
145
- const ERROR_BROKER_FRAME_SCHEMA = Type.Object({
146
- type: Type.Literal("error"),
147
- message: Type.String(),
148
- });
149
- export const CLIENT_FRAME_SCHEMA = Type.Union([
150
- REGISTER_CLIENT_FRAME_SCHEMA,
151
- UNREGISTER_CLIENT_FRAME_SCHEMA,
152
- LIST_CLIENT_FRAME_SCHEMA,
153
- SEND_CLIENT_FRAME_SCHEMA,
154
- INCOMING_ACK_CLIENT_FRAME_SCHEMA,
155
- ]);
156
- export const BROKER_FRAME_SCHEMA = Type.Union([
157
- REGISTERED_BROKER_FRAME_SCHEMA,
158
- REGISTER_FAILED_BROKER_FRAME_SCHEMA,
159
- SESSIONS_BROKER_FRAME_SCHEMA,
160
- INCOMING_BROKER_FRAME_SCHEMA,
161
- SEND_RESULT_BROKER_FRAME_SCHEMA,
162
- ERROR_BROKER_FRAME_SCHEMA,
163
- ]);
@@ -1,36 +0,0 @@
1
- import { Value } from "typebox/value";
2
- export function isTypeBoxValue(schema, value) {
3
- return Value.Check(schema, value);
4
- }
5
- export function parseTypeBoxValue(schema, value, context) {
6
- if (Value.Check(schema, value)) {
7
- return value;
8
- }
9
- throw new Error(formatTypeBoxError(schema, value, context));
10
- }
11
- export function safeParseTypeBoxValue(schema, value) {
12
- return Value.Check(schema, value) ? value : undefined;
13
- }
14
- export function parseTypeBoxRows(schema, value, context) {
15
- if (!Array.isArray(value)) {
16
- throw new Error(`${context}: expected an array of rows.`);
17
- }
18
- return value.map((row, index) => parseTypeBoxValue(schema, row, `${context} at row ${index + 1}`));
19
- }
20
- export function safeParseTypeBoxJson(schema, raw) {
21
- try {
22
- const parsed = JSON.parse(raw);
23
- return safeParseTypeBoxValue(schema, parsed);
24
- }
25
- catch {
26
- return undefined;
27
- }
28
- }
29
- function formatTypeBoxError(schema, value, context) {
30
- const firstError = Value.Errors(schema, value)[0];
31
- if (!firstError) {
32
- return `${context}: invalid value.`;
33
- }
34
- const path = firstError.instancePath.length > 0 ? firstError.instancePath : "/";
35
- return `${context}: ${path} ${firstError.message}`;
36
- }