open-research-protocol 0.4.16 → 0.4.18
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/cli/orp.py +67 -27
- package/docs/ORP_LINK_RUNNER_PLAN.md +6 -6
- package/docs/ORP_PUBLIC_LAUNCH_CHECKLIST.md +2 -2
- package/docs/ORP_REASONING_KERNEL_AGENT_PILOT.md +3 -3
- package/docs/ORP_REASONING_KERNEL_AGENT_REPLICATION.md +2 -2
- package/docs/ORP_REASONING_KERNEL_CANONICAL_CONTINUATION_PILOT.md +2 -2
- package/docs/ORP_REASONING_KERNEL_COMPARISON_PILOT.md +4 -4
- package/docs/ORP_REASONING_KERNEL_CONTINUATION_PILOT.md +3 -3
- package/docs/ORP_REASONING_KERNEL_EVALUATION_PLAN.md +8 -8
- package/docs/ORP_REASONING_KERNEL_EVIDENCE_MATRIX.md +25 -25
- package/docs/ORP_REASONING_KERNEL_EVOLUTION.md +4 -4
- package/docs/ORP_REASONING_KERNEL_PICKUP_PILOT.md +4 -4
- package/docs/ORP_REASONING_KERNEL_TECHNICAL_VALIDATION.md +19 -19
- package/docs/ORP_REASONING_KERNEL_V0_1.md +8 -8
- package/package.json +1 -1
- package/packages/orp-workspace-launcher/README.md +5 -5
- package/packages/orp-workspace-launcher/src/ledger.js +179 -47
- package/packages/orp-workspace-launcher/src/orp-command.js +16 -16
- package/packages/orp-workspace-launcher/test/ledger.test.js +119 -0
- package/packages/orp-workspace-launcher/test/orp-command.test.js +6 -0
- package/scripts/render-terminal-demo.py +3 -3
|
@@ -97,6 +97,32 @@ test("parseWorkspaceAddTabArgs accepts explicit resume metadata", () => {
|
|
|
97
97
|
assert.equal(parsed.json, true);
|
|
98
98
|
});
|
|
99
99
|
|
|
100
|
+
test("parseWorkspaceAddTabArgs resolves --here and --current-codex", () => {
|
|
101
|
+
const originalThreadId = process.env.CODEX_THREAD_ID;
|
|
102
|
+
const originalCwd = process.cwd();
|
|
103
|
+
process.env.CODEX_THREAD_ID = "019d4f24-c8ba-78b2-a726-48b1ce9f0fe9";
|
|
104
|
+
process.chdir("/Volumes/Code_2TB/code/orp");
|
|
105
|
+
try {
|
|
106
|
+
const parsed = parseWorkspaceAddTabArgs([
|
|
107
|
+
"main",
|
|
108
|
+
"--here",
|
|
109
|
+
"--current-codex",
|
|
110
|
+
]);
|
|
111
|
+
|
|
112
|
+
assert.equal(parsed.ideaId, "main");
|
|
113
|
+
assert.equal(parsed.path, "/Volumes/Code_2TB/code/orp");
|
|
114
|
+
assert.equal(parsed.resumeTool, "codex");
|
|
115
|
+
assert.equal(parsed.resumeSessionId, "019d4f24-c8ba-78b2-a726-48b1ce9f0fe9");
|
|
116
|
+
} finally {
|
|
117
|
+
process.chdir(originalCwd);
|
|
118
|
+
if (originalThreadId == null) {
|
|
119
|
+
delete process.env.CODEX_THREAD_ID;
|
|
120
|
+
} else {
|
|
121
|
+
process.env.CODEX_THREAD_ID = originalThreadId;
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
});
|
|
125
|
+
|
|
100
126
|
test("parseWorkspaceCreateArgs validates slug titles and optional seed metadata", () => {
|
|
101
127
|
const parsed = parseWorkspaceCreateArgs([
|
|
102
128
|
"main-cody-1",
|
|
@@ -144,6 +170,63 @@ test("addTabToManifest canonicalizes Claude resume commands from tool plus sessi
|
|
|
144
170
|
assert.equal(result.manifest.tabs[2]?.sessionId, "claude-456");
|
|
145
171
|
});
|
|
146
172
|
|
|
173
|
+
test("addTabToManifest updates an existing matching tab instead of appending a duplicate", () => {
|
|
174
|
+
const result = addTabToManifest(sampleManifest(), {
|
|
175
|
+
path: "/Volumes/Code_2TB/code/orp",
|
|
176
|
+
title: "orp",
|
|
177
|
+
resumeTool: "codex",
|
|
178
|
+
resumeSessionId: "019d4f24-c8ba-78b2-a726-48b1ce9f0fe9",
|
|
179
|
+
});
|
|
180
|
+
|
|
181
|
+
assert.equal(result.added, false);
|
|
182
|
+
assert.equal(result.updated, true);
|
|
183
|
+
assert.equal(result.mutation, "updated");
|
|
184
|
+
assert.equal(result.manifest.tabs.length, 2);
|
|
185
|
+
assert.equal(result.manifest.tabs[0]?.resumeCommand, "codex resume 019d4f24-c8ba-78b2-a726-48b1ce9f0fe9");
|
|
186
|
+
});
|
|
187
|
+
|
|
188
|
+
test("addTabToManifest preserves existing resume metadata when no new resume is provided", () => {
|
|
189
|
+
const result = addTabToManifest(sampleManifest(), {
|
|
190
|
+
path: "/Volumes/Code_2TB/code/frg-site",
|
|
191
|
+
title: "frg-site",
|
|
192
|
+
});
|
|
193
|
+
|
|
194
|
+
assert.equal(result.added, false);
|
|
195
|
+
assert.equal(result.updated, false);
|
|
196
|
+
assert.equal(result.unchanged, true);
|
|
197
|
+
assert.equal(result.mutation, "unchanged");
|
|
198
|
+
assert.equal(result.manifest.tabs.length, 2);
|
|
199
|
+
assert.equal(result.manifest.tabs[1]?.resumeCommand, "codex resume 019d348d-5031-78e1-9840-a66deaac33ae");
|
|
200
|
+
});
|
|
201
|
+
|
|
202
|
+
test("addTabToManifest asks for a title when multiple saved tabs share a path", () => {
|
|
203
|
+
const manifest = normalizeWorkspaceManifest({
|
|
204
|
+
version: "1",
|
|
205
|
+
workspaceId: "main-cody-1",
|
|
206
|
+
title: "main-cody-1",
|
|
207
|
+
tabs: [
|
|
208
|
+
{
|
|
209
|
+
title: "longevity-research",
|
|
210
|
+
path: "/Volumes/Code_2TB/code/longevity-research",
|
|
211
|
+
},
|
|
212
|
+
{
|
|
213
|
+
title: "longevity-research (2)",
|
|
214
|
+
path: "/Volumes/Code_2TB/code/longevity-research",
|
|
215
|
+
},
|
|
216
|
+
],
|
|
217
|
+
});
|
|
218
|
+
|
|
219
|
+
assert.throws(
|
|
220
|
+
() =>
|
|
221
|
+
addTabToManifest(manifest, {
|
|
222
|
+
path: "/Volumes/Code_2TB/code/longevity-research",
|
|
223
|
+
resumeTool: "codex",
|
|
224
|
+
resumeSessionId: "019d4f24-c8ba-78b2-a726-48b1ce9f0fe9",
|
|
225
|
+
}),
|
|
226
|
+
/Multiple saved tabs already use this path/,
|
|
227
|
+
);
|
|
228
|
+
});
|
|
229
|
+
|
|
147
230
|
test("removeTabsFromManifest can target a saved tab by path and resume session id", () => {
|
|
148
231
|
const result = removeTabsFromManifest(sampleManifest(), {
|
|
149
232
|
path: "/Volumes/Code_2TB/code/frg-site",
|
|
@@ -186,6 +269,42 @@ test("runWorkspaceAddTab updates a local workspace manifest file", async () => {
|
|
|
186
269
|
});
|
|
187
270
|
});
|
|
188
271
|
|
|
272
|
+
test("runWorkspaceAddTab upserts an existing tab and returns the rendered recovery command", async () => {
|
|
273
|
+
await withTempConfigHome(async () => {
|
|
274
|
+
const tempDir = await makeTempDir();
|
|
275
|
+
const manifestPath = path.join(tempDir, "workspace.json");
|
|
276
|
+
await fs.writeFile(manifestPath, `${JSON.stringify(sampleManifest(), null, 2)}\n`, "utf8");
|
|
277
|
+
|
|
278
|
+
const { code, stdout } = await captureStdout(() =>
|
|
279
|
+
runWorkspaceAddTab([
|
|
280
|
+
"--workspace-file",
|
|
281
|
+
manifestPath,
|
|
282
|
+
"--path",
|
|
283
|
+
"/Volumes/Code_2TB/code/orp",
|
|
284
|
+
"--resume-tool",
|
|
285
|
+
"codex",
|
|
286
|
+
"--resume-session-id",
|
|
287
|
+
"019d4f24-c8ba-78b2-a726-48b1ce9f0fe9",
|
|
288
|
+
"--json",
|
|
289
|
+
]),
|
|
290
|
+
);
|
|
291
|
+
const payload = JSON.parse(stdout);
|
|
292
|
+
const saved = JSON.parse(await fs.readFile(manifestPath, "utf8"));
|
|
293
|
+
|
|
294
|
+
assert.equal(code, 0);
|
|
295
|
+
assert.equal(payload.action, "add-tab");
|
|
296
|
+
assert.equal(payload.mutation, "updated");
|
|
297
|
+
assert.equal(payload.tabCount, 2);
|
|
298
|
+
assert.equal(payload.tab.resumeCommand, "codex resume 019d4f24-c8ba-78b2-a726-48b1ce9f0fe9");
|
|
299
|
+
assert.equal(
|
|
300
|
+
payload.tab.restartCommand,
|
|
301
|
+
"cd '/Volumes/Code_2TB/code/orp' && codex resume 019d4f24-c8ba-78b2-a726-48b1ce9f0fe9",
|
|
302
|
+
);
|
|
303
|
+
assert.equal(saved.tabs.length, 2);
|
|
304
|
+
assert.equal(saved.tabs[0]?.resumeCommand, "codex resume 019d4f24-c8ba-78b2-a726-48b1ce9f0fe9");
|
|
305
|
+
});
|
|
306
|
+
});
|
|
307
|
+
|
|
189
308
|
test("runWorkspaceRemoveTab updates a local workspace manifest file", async () => {
|
|
190
309
|
await withTempConfigHome(async () => {
|
|
191
310
|
const tempDir = await makeTempDir();
|
|
@@ -29,10 +29,16 @@ test("runOrpWorkspaceCommand shows the ledger-first help surface", async () => {
|
|
|
29
29
|
const { code, stdout } = await captureStdout(() => runOrpWorkspaceCommand(["-h"]));
|
|
30
30
|
|
|
31
31
|
assert.equal(code, 0);
|
|
32
|
+
assert.match(stdout, /orp workspace list \[--json\]/);
|
|
33
|
+
assert.match(stdout, /orp workspace add-tab <name-or-id>/);
|
|
34
|
+
assert.match(stdout, /--here/);
|
|
35
|
+
assert.match(stdout, /--current-codex/);
|
|
36
|
+
assert.match(stdout, /orp workspace remove-tab <name-or-id>/);
|
|
32
37
|
assert.match(stdout, /orp workspace ledger <name-or-id>/);
|
|
33
38
|
assert.match(stdout, /orp workspace ledger add <name-or-id>/);
|
|
34
39
|
assert.match(stdout, /orp workspace ledger remove <name-or-id>/);
|
|
35
40
|
assert.match(stdout, /orp workspace tabs <name-or-id>/);
|
|
41
|
+
assert.match(stdout, /Compatibility alias for the same tabs\/add\/remove ledger flow/);
|
|
36
42
|
});
|
|
37
43
|
|
|
38
44
|
test("runOrpWorkspaceCommand routes ledger help to the tabs help surface", async () => {
|
|
@@ -75,12 +75,12 @@ SCENES = [
|
|
|
75
75
|
"output_font": "small",
|
|
76
76
|
"line_height": 30,
|
|
77
77
|
"output": [
|
|
78
|
-
("ORP 0.4.
|
|
78
|
+
("ORP 0.4.16", ACCENT),
|
|
79
79
|
("Agent-first CLI for workspace ledgers, secrets, scheduling, and research workflows.", INK),
|
|
80
80
|
("Repo", SKY),
|
|
81
|
-
(" root:
|
|
81
|
+
(" root: ~/code/open-research-protocol", INK),
|
|
82
82
|
(" config: orp.yml (missing)", ACCENT),
|
|
83
|
-
(" git: yes, branch=main, commit=
|
|
83
|
+
(" git: yes, branch=main, commit=1a2b3c4", SOFT),
|
|
84
84
|
("Daily Loop", SKY),
|
|
85
85
|
(" orp workspace tabs main", ACCENT),
|
|
86
86
|
(' orp secrets add --alias <alias> --label "<label>" --provider <provider>', INK),
|