summaryrefslogtreecommitdiff
path: root/src/app
diff options
context:
space:
mode:
authortanaka takashi <isazaka@gmail.com>2026-07-04 17:21:32 +0900
committertanaka takashi <isazaka@gmail.com>2026-07-04 17:21:32 +0900
commit0634f2048c7c9a474aab1d8104b964b3bf70a064 (patch)
tree508c305a64cbd3b01f5146776e22865d283d5dbb /src/app
parenteb5e9d9f37bda7d78f69614da70402357794168a (diff)
feat(P1-002): migrate offline JSONL import/export to dedicated CLI
- Replace the MCP import_messages tool with standalone CLI commands: iny-convmem-mcp --data-dir <path> --import <file> iny-convmem-mcp --data-dir <path> --export <file> - Add src/cli/{import,export,cli.h} and a CTest process test (tiny-convmem-mcp.cli) covering round-trip, manifest generation, overwrite/reject policies, and include_deleted export. - Fix Debug heap corruption in iny_store_import() by deep-copying imported messages instead of taking ownership of caller-allocated records, which were later freed by the caller. - Remove the now-redundant src/mcp/tools/import_messages.c and keep the tool registry at 7 MCP tools. - Update docs/development-plan.md (P1-002 complete) and docs/implementation-status.md with CLI test coverage.
Diffstat (limited to 'src/app')
-rw-r--r--src/app/main.c88
1 files changed, 81 insertions, 7 deletions
diff --git a/src/app/main.c b/src/app/main.c
index f73b314..415e999 100644
--- a/src/app/main.c
+++ b/src/app/main.c
@@ -2,6 +2,7 @@
#include <stdlib.h>
#include <string.h>
+#include "cli/cli.h"
#include "mcp/server.h"
#include "storage/store.h"
#include "sys/system.h"
@@ -11,7 +12,75 @@
static void
usage(FILE *stream)
{
- fprintf(stream, "Usage: tiny-convmem-mcp --data-dir <path>\n");
+ fprintf(stream,
+ "Usage: tiny-convmem-mcp --data-dir <path> [command]\n"
+ "Commands:\n"
+ " (none) Run the MCP server (default)\n"
+ " --import <file> [--policy overwrite|reject]\n"
+ " Import a JSONL export into the store\n"
+ " --export <file> [--session <id>] [--include-deleted]\n"
+ " Export the store to a JSONL file (- for stdout)\n");
+}
+
+static const char *
+find_argument(const tiny_sys_arguments_t *arguments, const char *name)
+{
+ size_t index;
+ for (index = 1; index + 1 < arguments->count; ++index)
+ {
+ if (strcmp(arguments->values[index], name) == 0)
+ {
+ return arguments->values[index + 1];
+ }
+ }
+ return NULL;
+}
+
+static int
+flag_present(const tiny_sys_arguments_t *arguments, const char *name)
+{
+ size_t index;
+ for (index = 1; index < arguments->count; ++index)
+ {
+ if (strcmp(arguments->values[index], name) == 0)
+ {
+ return 1;
+ }
+ }
+ return 0;
+}
+
+static int
+run_server(tiny_store_t *store)
+{
+ int result = tiny_convmem_server_run(stdin, stdout, store);
+ if (result != 0)
+ {
+ fprintf(stderr, "tiny-convmem-mcp stopped with error code %d\n", result);
+ }
+ return result;
+}
+
+static int
+run_cli_command(tiny_store_t *store, const tiny_sys_arguments_t *arguments)
+{
+ tiny_cli_options_t options = { 0 };
+ options.data_dir = arguments->values[2];
+ options.import_path = find_argument(arguments, "--import");
+ options.export_path = find_argument(arguments, "--export");
+ options.session_id = find_argument(arguments, "--session");
+ options.policy_name = find_argument(arguments, "--policy");
+ options.include_deleted = flag_present(arguments, "--include-deleted");
+
+ if (options.import_path)
+ {
+ return tiny_cli_import(store, &options);
+ }
+ if (options.export_path)
+ {
+ return tiny_cli_export(store, &options);
+ }
+ return 2;
}
static int
@@ -21,17 +90,26 @@ run(const tiny_sys_arguments_t *arguments)
tiny_store_t *store = NULL;
tiny_store_status_t status;
int result;
+ int server_mode = 0;
if (arguments->count == 2 && strcmp(arguments->values[1], "--help") == 0)
{
usage(stdout);
return 0;
}
- if (arguments->count != 3 || strcmp(arguments->values[1], "--data-dir") != 0
+ if (arguments->count < 3 || strcmp(arguments->values[1], "--data-dir") != 0
|| arguments->values[2][0] == '\0')
{
usage(stderr);
return 2;
}
+ server_mode = (arguments->count == 3)
+ || (arguments->count == 5 && strcmp(arguments->values[3], "--import") != 0
+ && strcmp(arguments->values[3], "--export") != 0);
+ if (!server_mode && arguments->count < 5)
+ {
+ usage(stderr);
+ return 2;
+ }
absolute = tiny_sys_path_absolute(arguments->values[2]);
if (absolute == NULL)
{
@@ -45,12 +123,8 @@ run(const tiny_sys_arguments_t *arguments)
fprintf(stderr, "unable to open conversation store: %s\n", tiny_store_status_name(status));
return status == TINY_STORE_BUSY ? 3 : 1;
}
- result = tiny_convmem_server_run(stdin, stdout, store);
+ result = server_mode ? run_server(store) : run_cli_command(store, arguments);
tiny_store_close(store);
- if (result != 0)
- {
- fprintf(stderr, "tiny-convmem-mcp stopped with error code %d\n", result);
- }
return result;
}