waypoint-codex 0.18.0 → 0.18.1
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 +9 -0
- package/dist/src/core.js +1 -0
- package/dist/src/templates.js +2 -0
- package/package.json +1 -1
- package/templates/.waypoint/scripts/prepare-context.mjs +146 -33
package/README.md
CHANGED
|
@@ -189,6 +189,15 @@ The continuity story matters:
|
|
|
189
189
|
- `.waypoint/context/RECENT_THREAD.md` helps the agent retain the important
|
|
190
190
|
parts of the previous conversation
|
|
191
191
|
|
|
192
|
+
Waypoint defaults to Codex transcript discovery.
|
|
193
|
+
If you use Pi instead, set this in `.waypoint/config.toml`:
|
|
194
|
+
|
|
195
|
+
```toml
|
|
196
|
+
coding_agent = "pi"
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
Supported values are `"codex"` and `"pi"`.
|
|
200
|
+
|
|
192
201
|
## Best fit
|
|
193
202
|
|
|
194
203
|
Waypoint is most useful when you want:
|
package/dist/src/core.js
CHANGED
|
@@ -143,6 +143,7 @@ function buildWaypointConfig(projectRoot, existingConfig, options) {
|
|
|
143
143
|
return {
|
|
144
144
|
version: existingConfig?.version ?? defaults.version,
|
|
145
145
|
profile: options.profile,
|
|
146
|
+
coding_agent: existingConfig?.coding_agent ?? defaults.coding_agent,
|
|
146
147
|
workspace_file: existingConfig?.workspace_file ?? defaults.workspace_file,
|
|
147
148
|
docs_dirs: configuredRootDirs(projectRoot, existingConfig?.docs_dirs, existingConfig?.docs_dir, DEFAULT_DOCS_DIR).map((dir) => path.relative(projectRoot, dir).split(path.sep).join("/")),
|
|
148
149
|
plans_dirs: configuredRootDirs(projectRoot, existingConfig?.plans_dirs, existingConfig?.plans_dir, DEFAULT_PLANS_DIR).map((dir) => path.relative(projectRoot, dir).split(path.sep).join("/")),
|
package/dist/src/templates.js
CHANGED
|
@@ -30,6 +30,7 @@ export function defaultWaypointConfig(options) {
|
|
|
30
30
|
return {
|
|
31
31
|
version: 1,
|
|
32
32
|
profile: options.profile,
|
|
33
|
+
coding_agent: "codex",
|
|
33
34
|
workspace_file: ".waypoint/WORKSPACE.md",
|
|
34
35
|
docs_dirs: [".waypoint/docs"],
|
|
35
36
|
plans_dirs: [".waypoint/plans"],
|
|
@@ -44,6 +45,7 @@ export function renderWaypointConfig(config) {
|
|
|
44
45
|
const renderedConfig = {
|
|
45
46
|
version: config.version,
|
|
46
47
|
profile: config.profile,
|
|
48
|
+
coding_agent: config.coding_agent,
|
|
47
49
|
workspace_file: config.workspace_file,
|
|
48
50
|
docs_dirs: config.docs_dirs,
|
|
49
51
|
plans_dirs: config.plans_dirs,
|
package/package.json
CHANGED
|
@@ -116,7 +116,7 @@ function renderPullRequestBlock(result, emptyMessage) {
|
|
|
116
116
|
return result.stdout || emptyMessage;
|
|
117
117
|
}
|
|
118
118
|
|
|
119
|
-
const
|
|
119
|
+
const CODEX_SESSION_DIR_NAMES = ["sessions", "archived_sessions"];
|
|
120
120
|
const SECRET_PATTERNS = [
|
|
121
121
|
/npm_[A-Za-z0-9]+/g,
|
|
122
122
|
/github_pat_[A-Za-z0-9_]+/g,
|
|
@@ -132,6 +132,29 @@ function codexHome() {
|
|
|
132
132
|
return process.env.CODEX_HOME || path.join(os.homedir(), ".codex");
|
|
133
133
|
}
|
|
134
134
|
|
|
135
|
+
function piAgentHome() {
|
|
136
|
+
return process.env.PI_AGENT_HOME || path.join(os.homedir(), ".pi", "agent");
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
function loadCodingAgent(projectRoot) {
|
|
140
|
+
const configPath = path.join(projectRoot, ".waypoint", "config.toml");
|
|
141
|
+
if (!existsSync(configPath)) {
|
|
142
|
+
return "codex";
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
const configText = readFileSync(configPath, "utf8");
|
|
146
|
+
const match = configText.match(/^\s*coding_agent\s*=\s*"(codex|pi)"\s*$/m);
|
|
147
|
+
return match?.[1] || "codex";
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
function codingAgentLabel(codingAgent) {
|
|
151
|
+
return codingAgent === "pi" ? "Pi" : "Codex";
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
function codingAgentHome(codingAgent) {
|
|
155
|
+
return codingAgent === "pi" ? piAgentHome() : codexHome();
|
|
156
|
+
}
|
|
157
|
+
|
|
135
158
|
function redactSecrets(text) {
|
|
136
159
|
return SECRET_PATTERNS.reduce((current, pattern) => current.replace(pattern, "[REDACTED]"), text);
|
|
137
160
|
}
|
|
@@ -181,7 +204,7 @@ function collectSessionFiles(rootDir) {
|
|
|
181
204
|
return files;
|
|
182
205
|
}
|
|
183
206
|
|
|
184
|
-
function
|
|
207
|
+
function extractCodexMessageText(content) {
|
|
185
208
|
if (!Array.isArray(content)) {
|
|
186
209
|
return "";
|
|
187
210
|
}
|
|
@@ -192,6 +215,17 @@ function extractMessageText(content) {
|
|
|
192
215
|
.trim();
|
|
193
216
|
}
|
|
194
217
|
|
|
218
|
+
function extractPiMessageText(content) {
|
|
219
|
+
if (!Array.isArray(content)) {
|
|
220
|
+
return "";
|
|
221
|
+
}
|
|
222
|
+
return content
|
|
223
|
+
.filter((block) => block?.type === "text")
|
|
224
|
+
.map((block) => (typeof block?.text === "string" ? block.text : ""))
|
|
225
|
+
.join("")
|
|
226
|
+
.trim();
|
|
227
|
+
}
|
|
228
|
+
|
|
195
229
|
function isBootstrapNoise(role, text) {
|
|
196
230
|
return role === "user" && text.startsWith("# AGENTS.md instructions for ");
|
|
197
231
|
}
|
|
@@ -213,11 +247,33 @@ function mergeConsecutiveTurns(turns) {
|
|
|
213
247
|
return merged;
|
|
214
248
|
}
|
|
215
249
|
|
|
216
|
-
function
|
|
250
|
+
function finalizeParsedSession(sessionFile, projectRoot, sessionId, sessionCwd, sessionStartedAt, rawTurns, compactionBoundaries) {
|
|
251
|
+
if (!sessionCwd || !isWithinPath(sessionCwd, projectRoot)) {
|
|
252
|
+
return null;
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
const selectedFromPreCompaction = compactionBoundaries.length > 0;
|
|
256
|
+
const relevantTurns = selectedFromPreCompaction ? rawTurns.slice(0, compactionBoundaries.at(-1)) : rawTurns;
|
|
257
|
+
const turns = mergeConsecutiveTurns(relevantTurns);
|
|
258
|
+
if (turns.length === 0) {
|
|
259
|
+
return null;
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
return {
|
|
263
|
+
path: sessionFile,
|
|
264
|
+
sessionId,
|
|
265
|
+
sessionCwd,
|
|
266
|
+
turns,
|
|
267
|
+
compactionCount: compactionBoundaries.length,
|
|
268
|
+
selectedFromPreCompaction,
|
|
269
|
+
sessionStartedAt,
|
|
270
|
+
};
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
function parseCodexSession(sessionFile, projectRoot) {
|
|
217
274
|
let sessionId = null;
|
|
218
275
|
let sessionCwd = null;
|
|
219
276
|
let sessionStartedAt = null;
|
|
220
|
-
let compactionCount = 0;
|
|
221
277
|
const rawTurns = [];
|
|
222
278
|
const compactionBoundaries = [];
|
|
223
279
|
|
|
@@ -250,7 +306,6 @@ function parseSession(sessionFile, projectRoot) {
|
|
|
250
306
|
}
|
|
251
307
|
|
|
252
308
|
if (parsed.type === "compacted") {
|
|
253
|
-
compactionCount += 1;
|
|
254
309
|
compactionBoundaries.push(rawTurns.length);
|
|
255
310
|
continue;
|
|
256
311
|
}
|
|
@@ -264,7 +319,7 @@ function parseSession(sessionFile, projectRoot) {
|
|
|
264
319
|
continue;
|
|
265
320
|
}
|
|
266
321
|
|
|
267
|
-
const text = redactSecrets(
|
|
322
|
+
const text = redactSecrets(extractCodexMessageText(parsed.payload?.content));
|
|
268
323
|
if (!text || isBootstrapNoise(role, text)) {
|
|
269
324
|
continue;
|
|
270
325
|
}
|
|
@@ -277,37 +332,90 @@ function parseSession(sessionFile, projectRoot) {
|
|
|
277
332
|
});
|
|
278
333
|
}
|
|
279
334
|
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
}
|
|
335
|
+
return finalizeParsedSession(sessionFile, projectRoot, sessionId, sessionCwd, sessionStartedAt, rawTurns, compactionBoundaries);
|
|
336
|
+
}
|
|
283
337
|
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
338
|
+
function parsePiSession(sessionFile, projectRoot) {
|
|
339
|
+
let sessionId = null;
|
|
340
|
+
let sessionCwd = null;
|
|
341
|
+
let sessionStartedAt = null;
|
|
342
|
+
const rawTurns = [];
|
|
343
|
+
const compactionBoundaries = [];
|
|
344
|
+
|
|
345
|
+
for (const line of readFileSync(sessionFile, "utf8").split("\n")) {
|
|
346
|
+
if (!line.trim()) {
|
|
347
|
+
continue;
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
let parsed;
|
|
351
|
+
try {
|
|
352
|
+
parsed = JSON.parse(line);
|
|
353
|
+
} catch {
|
|
354
|
+
continue;
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
if (parsed.type === "session") {
|
|
358
|
+
if (typeof parsed.id === "string") {
|
|
359
|
+
sessionId = parsed.id;
|
|
360
|
+
}
|
|
361
|
+
if (typeof parsed.cwd === "string") {
|
|
362
|
+
sessionCwd = parsed.cwd;
|
|
363
|
+
}
|
|
364
|
+
if (typeof parsed.timestamp === "string") {
|
|
365
|
+
sessionStartedAt = parsed.timestamp;
|
|
366
|
+
}
|
|
367
|
+
continue;
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
if (parsed.type === "compaction") {
|
|
371
|
+
compactionBoundaries.push(rawTurns.length);
|
|
372
|
+
continue;
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
if (parsed.type !== "message") {
|
|
376
|
+
continue;
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
const role = parsed.message?.role;
|
|
380
|
+
if (role !== "user" && role !== "assistant") {
|
|
381
|
+
continue;
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
const text = redactSecrets(extractPiMessageText(parsed.message?.content));
|
|
385
|
+
if (!text || isBootstrapNoise(role, text)) {
|
|
386
|
+
continue;
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
rawTurns.push({
|
|
390
|
+
role,
|
|
391
|
+
text,
|
|
392
|
+
timestamp: parsed.timestamp || parsed.message?.timestamp || null,
|
|
393
|
+
messageCount: 1,
|
|
394
|
+
});
|
|
289
395
|
}
|
|
290
396
|
|
|
291
|
-
return
|
|
292
|
-
path: sessionFile,
|
|
293
|
-
sessionId,
|
|
294
|
-
sessionCwd,
|
|
295
|
-
turns,
|
|
296
|
-
compactionCount,
|
|
297
|
-
selectedFromPreCompaction,
|
|
298
|
-
sessionStartedAt,
|
|
299
|
-
};
|
|
397
|
+
return finalizeParsedSession(sessionFile, projectRoot, sessionId, sessionCwd, sessionStartedAt, rawTurns, compactionBoundaries);
|
|
300
398
|
}
|
|
301
399
|
|
|
302
|
-
function latestMatchingSession(projectRoot, threadIdOverride = null) {
|
|
400
|
+
function latestMatchingSession(projectRoot, codingAgent, threadIdOverride = null) {
|
|
303
401
|
const matches = [];
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
402
|
+
|
|
403
|
+
if (codingAgent === "pi") {
|
|
404
|
+
for (const sessionFile of collectSessionFiles(path.join(piAgentHome(), "sessions"))) {
|
|
405
|
+
const parsed = parsePiSession(sessionFile, projectRoot);
|
|
307
406
|
if (parsed) {
|
|
308
407
|
matches.push(parsed);
|
|
309
408
|
}
|
|
310
409
|
}
|
|
410
|
+
} else {
|
|
411
|
+
for (const dirName of CODEX_SESSION_DIR_NAMES) {
|
|
412
|
+
for (const sessionFile of collectSessionFiles(path.join(codexHome(), dirName))) {
|
|
413
|
+
const parsed = parseCodexSession(sessionFile, projectRoot);
|
|
414
|
+
if (parsed) {
|
|
415
|
+
matches.push(parsed);
|
|
416
|
+
}
|
|
417
|
+
}
|
|
418
|
+
}
|
|
311
419
|
}
|
|
312
420
|
|
|
313
421
|
const requestedThreadId = threadIdOverride || process.env.CODEX_THREAD_ID || null;
|
|
@@ -331,7 +439,10 @@ function latestMatchingSession(projectRoot, threadIdOverride = null) {
|
|
|
331
439
|
|
|
332
440
|
function writeRecentThread(contextDir, projectRoot, threadIdOverride = null) {
|
|
333
441
|
const filePath = path.join(contextDir, "RECENT_THREAD.md");
|
|
334
|
-
const
|
|
442
|
+
const codingAgent = loadCodingAgent(projectRoot);
|
|
443
|
+
const agentLabel = codingAgentLabel(codingAgent);
|
|
444
|
+
const agentHome = codingAgentHome(codingAgent);
|
|
445
|
+
const snapshot = latestMatchingSession(projectRoot, codingAgent, threadIdOverride);
|
|
335
446
|
const generatedAt = new Date().toString();
|
|
336
447
|
|
|
337
448
|
if (!snapshot) {
|
|
@@ -342,7 +453,7 @@ function writeRecentThread(contextDir, projectRoot, threadIdOverride = null) {
|
|
|
342
453
|
"",
|
|
343
454
|
`Generated by \`${path.relative(projectRoot, fileURLToPath(import.meta.url))}\` on ${generatedAt}.`,
|
|
344
455
|
"",
|
|
345
|
-
|
|
456
|
+
`No matching local ${agentLabel} session was found for this repo yet.`,
|
|
346
457
|
"",
|
|
347
458
|
].join("\n"),
|
|
348
459
|
"utf8"
|
|
@@ -358,10 +469,10 @@ function writeRecentThread(contextDir, projectRoot, threadIdOverride = null) {
|
|
|
358
469
|
"",
|
|
359
470
|
`Generated by \`${path.relative(projectRoot, fileURLToPath(import.meta.url))}\` on ${generatedAt}.`,
|
|
360
471
|
"",
|
|
361
|
-
`- Source session: \`${path.relative(
|
|
472
|
+
`- Source session: \`${path.relative(agentHome, snapshot.path)}\``,
|
|
362
473
|
`- Session cwd: \`${snapshot.sessionCwd}\``,
|
|
363
474
|
`- Compactions in source session: ${snapshot.compactionCount}`,
|
|
364
|
-
|
|
475
|
+
`- No compaction was found in the latest matching local ${agentLabel} session, so there is nothing to restore into startup context yet.`,
|
|
365
476
|
"",
|
|
366
477
|
].join("\n"),
|
|
367
478
|
"utf8"
|
|
@@ -370,7 +481,7 @@ function writeRecentThread(contextDir, projectRoot, threadIdOverride = null) {
|
|
|
370
481
|
}
|
|
371
482
|
|
|
372
483
|
const selectedTurns = snapshot.turns.slice(-MAX_RECENT_TURNS);
|
|
373
|
-
const relSessionPath = path.relative(
|
|
484
|
+
const relSessionPath = path.relative(agentHome, snapshot.path);
|
|
374
485
|
const lines = [
|
|
375
486
|
"# Recent Thread",
|
|
376
487
|
"",
|
|
@@ -435,6 +546,8 @@ function main() {
|
|
|
435
546
|
|
|
436
547
|
const docsIndexPath = writeDocsIndex(projectRoot);
|
|
437
548
|
const { outputPath: tracksIndexPath, activeTracks } = writeTracksIndex(projectRoot);
|
|
549
|
+
const codingAgent = loadCodingAgent(projectRoot);
|
|
550
|
+
const codingAgentLabelText = codingAgentLabel(codingAgent);
|
|
438
551
|
|
|
439
552
|
const currentTimezone = Intl.DateTimeFormat().resolvedOptions().timeZone;
|
|
440
553
|
const currentLocalDatetime = new Date().toString();
|
|
@@ -577,7 +690,7 @@ function main() {
|
|
|
577
690
|
`- \`${path.relative(projectRoot, uncommittedChangesPath)}\` — uncommitted change summary`,
|
|
578
691
|
`- \`${path.relative(projectRoot, recentCommitsPath)}\` — recent commits`,
|
|
579
692
|
`- \`${path.relative(projectRoot, prsPath)}\` — open and recently merged pull requests`,
|
|
580
|
-
`- \`${path.relative(projectRoot, recentThreadPath)}\` — latest meaningful turns from the local
|
|
693
|
+
`- \`${path.relative(projectRoot, recentThreadPath)}\` — latest meaningful turns from the local ${codingAgentLabelText} session for this repo`,
|
|
581
694
|
`- \`${path.relative(projectRoot, docsIndexPath)}\` — current docs index`,
|
|
582
695
|
`- \`${path.relative(projectRoot, tracksIndexPath)}\` — current tracker index`,
|
|
583
696
|
`- \`${path.relative(projectRoot, activeTrackersPath)}\` — active tracker summary`,
|