Skip to content

Commit 02007d8

Browse files
committed
feat(note): integrate Reply cell execution
1 parent 6408356 commit 02007d8

9 files changed

Lines changed: 382 additions & 13 deletions

File tree

CMakeLists.txt

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,17 @@ set(VIX_NOTE_MODULE_VERSION 0.2.0)
2020
# ============================================================================
2121

2222
get_property(_VIX_NOTE_MODULE_ALREADY_INCLUDED GLOBAL PROPERTY VIX_NOTE_MODULE_ALREADY_INCLUDED)
23+
2324
if(_VIX_NOTE_MODULE_ALREADY_INCLUDED)
2425
return()
2526
endif()
27+
2628
set_property(GLOBAL PROPERTY VIX_NOTE_MODULE_ALREADY_INCLUDED TRUE)
2729

30+
# ============================================================================
31+
# Standalone vs Umbrella
32+
# ============================================================================
33+
2834
if(CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR)
2935
project(vix_note
3036
VERSION ${VIX_NOTE_MODULE_VERSION}
@@ -74,6 +80,7 @@ set(VIX_NOTE_SOURCES
7480
src/storage/NoteStore.cpp
7581

7682
src/runtime/CppCellRunner.cpp
83+
src/runtime/ReplyCellRunner.cpp
7784
src/runtime/NoteSession.cpp
7885
src/runtime/NoteKernel.cpp
7986

@@ -136,6 +143,60 @@ else()
136143
vix_note_add_flag_if_supported(vix_note -Wpedantic)
137144
endif()
138145

146+
# ============================================================================
147+
# Dependency resolution helpers
148+
# ============================================================================
149+
150+
function(vix_note_append_if_exists out_var path_value)
151+
if(EXISTS "${path_value}")
152+
set(${out_var} "${${out_var}};${path_value}" PARENT_SCOPE)
153+
endif()
154+
endfunction()
155+
156+
# ============================================================================
157+
# Reply module
158+
# - ReplyCellRunner depends on vix::reply.
159+
# - Same style as CLI:
160+
# 1) use target already created by umbrella
161+
# 2) use local sibling module ../reply
162+
# 3) fallback to installed package
163+
# ============================================================================
164+
165+
get_filename_component(_VIX_NOTE_MODULES_DIR "${CMAKE_CURRENT_SOURCE_DIR}/.." ABSOLUTE)
166+
167+
set(_VIX_REPLY_DIR "${_VIX_NOTE_MODULES_DIR}/reply")
168+
169+
if(NOT TARGET vix::reply AND NOT TARGET vix::vix_reply)
170+
if(EXISTS "${_VIX_REPLY_DIR}/CMakeLists.txt")
171+
message(STATUS "[note] Building inside Vix repo -> resolving local reply module")
172+
173+
set(VIX_REPLY_BUILD_TESTS OFF CACHE BOOL "Build Vix Reply tests" FORCE)
174+
set(VIX_REPLY_BUILD_EXAMPLES OFF CACHE BOOL "Build Vix Reply examples" FORCE)
175+
176+
add_subdirectory("${_VIX_REPLY_DIR}" "${CMAKE_BINARY_DIR}/_vix_reply")
177+
else()
178+
message(STATUS "[note] Local reply module not found -> trying installed package")
179+
180+
find_package(vix_reply CONFIG QUIET)
181+
endif()
182+
endif()
183+
184+
if(TARGET vix::reply)
185+
message(STATUS "[note] Reply runtime enabled")
186+
target_link_libraries(vix_note PUBLIC vix::reply)
187+
elseif(TARGET vix::vix_reply)
188+
message(STATUS "[note] Reply runtime enabled")
189+
target_link_libraries(vix_note PUBLIC vix::vix_reply)
190+
else()
191+
message(FATAL_ERROR
192+
"Missing dependency for vix_note.\n"
193+
"Expected one of:\n"
194+
" - umbrella target vix::reply\n"
195+
" - local sibling module in ../reply\n"
196+
" - installed package providing vix::reply or vix::vix_reply"
197+
)
198+
endif()
199+
139200
# ============================================================================
140201
# Version string
141202
# ============================================================================

assets/index.html

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,14 @@ <h2 class="note-header__title" data-note-title>
7474
Add C++
7575
</button>
7676

77+
<button
78+
class="note-button note-button--ghost"
79+
type="button"
80+
data-action="add-reply"
81+
>
82+
Add Reply
83+
</button>
84+
7785
<button
7886
class="note-button note-button--ghost"
7987
type="button"

assets/js/note.js

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
save: '[data-action="save"]',
2323
addMarkdown: '[data-action="add-markdown"]',
2424
addCpp: '[data-action="add-cpp"]',
25+
addReply: '[data-action="add-reply"]',
2526
};
2627

2728
function $(selector, root = document) {
@@ -565,10 +566,16 @@
565566
setKernelStatus("Editing");
566567
setBusy(true);
567568

568-
const source =
569-
normalizeKind(kind) === "cpp"
570-
? '#include <iostream>\n\nint main()\n{\n std::cout << "Hello from Vix Note\\n";\n return 0;\n}\n'
571-
: "Write your explanation here.";
569+
let source = "Write your explanation here.";
570+
571+
if (normalizeKind(kind) === "cpp") {
572+
source =
573+
'#include <iostream>\n\nint main()\n{\n std::cout << "Hello from Vix Note\\n";\n return 0;\n}\n';
574+
}
575+
576+
if (normalizeKind(kind) === "reply") {
577+
source = 'x = 1 + 2 * 3\nprintln("x =", x)\n';
578+
}
572579

573580
try {
574581
await syncDirtyCells();
@@ -616,14 +623,15 @@
616623
await syncCell(cellElement);
617624

618625
const result = await api(
619-
"/api/run-all",
626+
`/api/cells/${key}/run`,
620627
{
621628
method: "POST",
622629
},
623630
{
624631
allowErrorResponse: true,
625632
},
626633
);
634+
627635
if (result.document) {
628636
renderDocument(result.document);
629637
} else if (result.cell) {
@@ -858,6 +866,11 @@
858866
return;
859867
}
860868

869+
if (action === "add-reply") {
870+
addCell("reply");
871+
return;
872+
}
873+
861874
if (action === "move-up") {
862875
moveCell(target, "up");
863876
return;

cmake/vix_noteConfig.cmake.in

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,13 @@
22

33
include(CMakeFindDependencyMacro)
44

5+
find_dependency(vix_reply CONFIG)
6+
7+
if(NOT TARGET vix::reply AND TARGET vix::vix_reply)
8+
add_library(vix::reply INTERFACE IMPORTED)
9+
target_link_libraries(vix::reply INTERFACE vix::vix_reply)
10+
endif()
11+
512
include("${CMAKE_CURRENT_LIST_DIR}/vix_noteTargets.cmake")
613

714
check_required_components(vix_note)

include/vix/note/runtime/NoteKernel.hpp

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
#include <vix/note/core/NoteResult.hpp>
2424
#include <vix/note/runtime/CppCellRunner.hpp>
2525
#include <vix/note/runtime/NoteSession.hpp>
26+
#include <vix/note/runtime/ReplyCellRunner.hpp>
2627

2728
#include <cstddef>
2829
#include <optional>
@@ -46,6 +47,11 @@ namespace vix::note
4647
*/
4748
CppCellRunnerOptions cppOptions;
4849

50+
/**
51+
* @brief Reply runner options used for Reply cells.
52+
*/
53+
ReplyCellRunnerOptions replyOptions;
54+
4955
/**
5056
* @brief Stops run_all() after the first failed executable cell.
5157
*/
@@ -299,10 +305,6 @@ namespace vix::note
299305
/**
300306
* @brief Runs a Reply cell.
301307
*
302-
* Reply execution is intentionally not implemented yet. Reply cells are
303-
* recognized by the kernel but currently return a skipped result until the
304-
* Reply runtime integration is added in a later version.
305-
*
306308
* @param cell Cell to run.
307309
* @return Execution result.
308310
*/
@@ -335,6 +337,11 @@ namespace vix::note
335337
* @brief C++ cell runner.
336338
*/
337339
CppCellRunner cppRunner_;
340+
341+
/**
342+
* @brief Reply cell runner.
343+
*/
344+
ReplyCellRunner replyRunner_;
338345
};
339346

340347
/**
Lines changed: 144 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,144 @@
1+
/**
2+
*
3+
* @file ReplyCellRunner.hpp
4+
* @author Gaspard Kirira
5+
*
6+
* @brief Reply cell execution helper for Vix Note.
7+
*
8+
* Copyright 2026, Gaspard Kirira.
9+
* All rights reserved.
10+
* https://github.com/vixcpp/note
11+
*
12+
* Use of this source code is governed by a MIT license
13+
* that can be found in the LICENSE file.
14+
*
15+
* Vix Note
16+
*
17+
*/
18+
19+
#ifndef VIX_NOTE_RUNTIME_REPLY_CELL_RUNNER_HPP
20+
#define VIX_NOTE_RUNTIME_REPLY_CELL_RUNNER_HPP
21+
22+
#include <vix/note/core/NoteCell.hpp>
23+
#include <vix/note/core/NoteResult.hpp>
24+
25+
#include <vix/reply/core/ReplyRuntime.hpp>
26+
27+
#include <string>
28+
#include <utility>
29+
#include <vector>
30+
31+
namespace vix::note
32+
{
33+
/**
34+
* @brief Options used when running a Reply note cell.
35+
*
36+
* ReplyCellRunner executes small Reply cells through the embeddable
37+
* Vix Reply runtime. It does not start the interactive terminal REPL.
38+
*/
39+
struct ReplyCellRunnerOptions
40+
{
41+
/**
42+
* @brief Runtime options passed to the embedded Reply runtime.
43+
*/
44+
vix::reply::ReplyRuntimeOptions runtimeOptions;
45+
46+
/**
47+
* @brief Arguments exposed through Vix.args().
48+
*/
49+
std::vector<std::string> args;
50+
51+
/**
52+
* @brief Enables debug metadata outputs.
53+
*/
54+
bool debugMode = false;
55+
};
56+
57+
/**
58+
* @brief Executes Reply cells through the embedded Reply runtime.
59+
*/
60+
class ReplyCellRunner
61+
{
62+
public:
63+
/**
64+
* @brief Creates a runner with default options.
65+
*/
66+
ReplyCellRunner();
67+
68+
/**
69+
* @brief Creates a runner with custom options.
70+
*
71+
* @param options Runner options.
72+
*/
73+
explicit ReplyCellRunner(ReplyCellRunnerOptions options);
74+
75+
/**
76+
* @brief Returns the current runner options.
77+
*
78+
* @return Runner options.
79+
*/
80+
const ReplyCellRunnerOptions &options() const noexcept;
81+
82+
/**
83+
* @brief Replaces the current runner options.
84+
*
85+
* @param options New runner options.
86+
*/
87+
void set_options(ReplyCellRunnerOptions options);
88+
89+
/**
90+
* @brief Runs raw Reply source code.
91+
*
92+
* @param source Reply source code.
93+
* @return Execution result.
94+
*/
95+
NoteResult run_source(const std::string &source);
96+
97+
/**
98+
* @brief Runs a Reply note cell.
99+
*
100+
* @param cell Cell to execute.
101+
* @return Execution result.
102+
*/
103+
NoteResult run_cell(const NoteCell &cell);
104+
105+
/**
106+
* @brief Clears the embedded Reply runtime state.
107+
*/
108+
void clear();
109+
110+
private:
111+
/**
112+
* @brief Rebuilds the embedded runtime from current options.
113+
*/
114+
void reset_runtime();
115+
116+
/**
117+
* @brief Runner options.
118+
*/
119+
ReplyCellRunnerOptions options_;
120+
121+
/**
122+
* @brief Embedded Reply runtime.
123+
*/
124+
vix::reply::ReplyRuntime runtime_;
125+
};
126+
127+
/**
128+
* @brief Runs raw Reply source code using default runner options.
129+
*
130+
* @param source Reply source code.
131+
* @return Execution result.
132+
*/
133+
NoteResult run_reply_source(const std::string &source);
134+
135+
/**
136+
* @brief Runs a Reply cell using default runner options.
137+
*
138+
* @param cell Cell to execute.
139+
* @return Execution result.
140+
*/
141+
NoteResult run_reply_cell(const NoteCell &cell);
142+
}
143+
144+
#endif // VIX_NOTE_RUNTIME_REPLY_CELL_RUNNER_HPP

src/runtime/NoteKernel.cpp

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -337,9 +337,7 @@ namespace vix::note
337337

338338
NoteResult NoteKernel::run_reply_cell(const NoteCell &cell)
339339
{
340-
(void)cell;
341-
342-
return NoteResult::skipped("Reply cell execution is not available yet");
340+
return replyRunner_.run_cell(cell);
343341
}
344342

345343
NoteResult NoteKernel::run_cpp_cell_internal(const NoteCell &cell)
@@ -353,6 +351,7 @@ namespace vix::note
353351

354352
session_.set_options(options_.sessionOptions);
355353
cppRunner_.set_options(options_.cppOptions);
354+
replyRunner_.set_options(options_.replyOptions);
356355
}
357356

358357
NoteKernelRunResult run_note(NoteDocument document)

0 commit comments

Comments
 (0)