Skip to content

refactor: init ocaml-version logseq-cli#12768

Merged
tiensonqin merged 52 commits into
masterfrom
refactor/ocaml-logseq-cli
Jun 16, 2026
Merged

refactor: init ocaml-version logseq-cli#12768
tiensonqin merged 52 commits into
masterfrom
refactor/ocaml-logseq-cli

Conversation

@RCmerci

@RCmerci RCmerci commented Jun 4, 2026

Copy link
Copy Markdown
Contributor
  • new type-safe logseq-cli written in ocaml
  • required tools: opam, dune(opam install dune)
  • build cmd: cd cli && dune build @all
  • test: cd cli && node _build/default/dist/logseq-cli.js

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 47f85e4108

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread cli/lib/cli_parse.ml
Comment on lines +93 to +96
let bool_option_value key options =
match option_value key options with
| Some value -> Some (String.lowercase_ascii (String.trim value) = "true")
| None -> if option_present key options then Some true else None

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Reject invalid boolean option values

For options parsed through bool_option_value (for example upsert property --hide, --public, list page --include-built-in, or show --linked-references), any value other than a case-insensitive true is silently treated as false. This means inputs like --hide tru or --linked-references maybe are accepted and change command behavior instead of producing an actionable invalid-options error, contrary to the CLI boundary behavior expected for user-supplied options. Please validate these values as only true/false when a value is provided.

Useful? React with 👍 / 👎.

Comment thread cli/lib/cli_action.ml
Comment thread cli/lib/cli_parse.ml
Comment thread cli/lib/sync.ml Outdated
Comment thread cli/lib/cli_primitive.ml
let prefix_len = String.length prefix in
String.length value >= prefix_len && String.sub value 0 prefix_len = prefix

let create_graph value = String.trim value

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Reject path-segment graph names before filesystem use

--graph values are only trimmed here, so empty strings and path-segment names like . or .. are accepted as graph names. Since filesystem commands later build paths with Filename.concat <root>/graphs (Graph_dir.encode_graph_dir_name graph), those inputs resolve to <root>/graphs, <root>/graphs/., or <root>/graphs/..; commands such as graph remove and backup operations can then operate on the graph root or CLI root instead of a graph directory. Reject empty, . and .. graph names at the boundary before constructing actions.

Useful? React with 👍 / 👎.

Comment thread cli/lib/cli_unix.ml Outdated
@RCmerci RCmerci force-pushed the refactor/ocaml-logseq-cli branch 2 times, most recently from 5546a6f to ee878ee Compare June 14, 2026 11:14
@RCmerci

RCmerci commented Jun 15, 2026

Copy link
Copy Markdown
Contributor Author

@codex, review again

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: ee878eebb3

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread package.json
Comment thread xxx Outdated
Comment thread cli/lib/cli_parse.ml
Comment on lines +63 to +66
match rest with
| value :: tail when not (is_option value) ->
loop ((key, Some value) :: options) positional tail
| _ -> loop ((key, None) :: options) positional rest)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Reject missing values for value options

When a value-taking option is followed by another option or by the end of argv, this records (key, None) and continues; later validation and config resolution treat that the same as the option being absent. For example, logseq --root-dir --graph work remove page --page Home silently falls back to the default root instead of failing that --root-dir has no value, which can make write commands target the wrong graph root after a CLI typo.

Useful? React with 👍 / 👎.

Comment thread cli/lib/cli.ml
Comment on lines +319 to +320
match ensure_root_config config with
| Error err ->

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Skip root setup for version output

Every parsed command reaches ensure_root_config here, so logseq --version resolves and creates/checks the default root (~/logseq) before returning build metadata. The docs explicitly call out that --version should exit without requiring repo/root-dir, so in a locked-down HOME or read-only root this read-only metadata command fails or mutates the filesystem even though the version action itself does not use graph storage.

Useful? React with 👍 / 👎.

Comment thread cli/lib/add.ml
Comment on lines +635 to +636
| Some _ -> failwith "tag not found"
| None -> failwith "tag not found")

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Return structured errors for missing tags

When upsert block --update-tags ... creates blocks and a supplied tag name/id resolves to no tag, this failwith rejects the effect instead of returning a Cli_result error; main.ml then prints a raw OCaml exception and bypasses the requested JSON/EDN error formatting. This is a normal user-input failure (missing/private tag), so create mode should report it through the same structured option-resolution path used by update mode.

Useful? React with 👍 / 👎.

Comment thread cli/lib/server_runtime.ml
Comment on lines +403 to +404
bind (find_repo_server config repo) (function
| Some server -> pure (Ok (invoke_config_of_server config server))

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Restart revision-mismatched daemons before reuse

When a graph command finds an existing db-worker-node for the repo, this returns that endpoint without comparing server.revision with the local CLI revision. The documented desktop/CLI contract says startup must restart a daemon with a different revision before returning a usable endpoint, so after an upgrade the new CLI can keep talking to a stale worker with an incompatible API or schema.

Useful? React with 👍 / 👎.

Comment thread cli/lib/server_command.ml
Comment on lines +128 to +129
(Server_runtime.cleanup_revision_mismatched_servers config
~cli_revision:"unknown") (function

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Use the local revision for server cleanup

server cleanup is documented to treat revision != local CLI revision as a mismatch, but it always passes the literal "unknown". In normal builds db-worker health reports the actual revision, so running cleanup will classify every CLI-owned server with a real revision as mismatched and stop it even when it already matches the current CLI.

Useful? React with 👍 / 👎.

Comment thread cli/lib/cli_parse.ml
Comment on lines +891 to +893
progress =
(if option_present "progress" options then Some true
else None);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Preserve explicit false for download progress

The tokenizer accepts boolean literals, and the docs say --progress false suppresses sync download progress, but this parse step discards the parsed value and records Some true whenever the option is present. As a result both --progress false and --progress=false force progress streaming instead of disabling it, which breaks scripted JSON/EDN downloads that explicitly turn progress off.

Useful? React with 👍 / 👎.

Comment thread cli/lib/sync.ml
Comment on lines +421 to +422
| None, Some repo -> Server_runtime.ensure_server config repo ~create_empty_db
| None, None -> Cli_effect.pure (Error (Error.missing_graph ()))

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Use a graphless endpoint for global sync commands

For graphless sync commands such as sync remote-graphs, config.repo is None and config.base_url is only set by LOGSEQ_CLI_BASE_URL, so normal user invocations fall through to Error.missing_graph before any remote graph request is made. These commands are documented as not requiring --graph; they need a real global/default endpoint path instead of requiring an unrelated graph worker.

Useful? React with 👍 / 👎.

Comment thread cli/lib/format_types.ml
| _, Some b, _, _, _, _, _, _ -> Js.Json.boolean b
| _, _, Some i, _, _, _, _, _ -> Js.Json.number (float_of_int i)
| _, _, _, Some f, _, _, _, _ -> Js.Json.number f
| _, _, _, _, Some s, _, _, _ -> Js.Json.string (strip_leading_colon s)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Preserve leading colons in JSON string values

This branch handles both EDN strings and keywords via as_string_like, then strips a leading colon from all of them. In JSON output, user data such as a block title or property value ":meeting" is serialized as "meeting", corrupting machine-readable output; only keyword values or map keys should have their EDN colon removed.

Useful? React with 👍 / 👎.

@tiensonqin tiensonqin force-pushed the refactor/ocaml-logseq-cli branch from 4a22405 to 61b1350 Compare June 16, 2026 05:25
@tiensonqin tiensonqin merged commit 7cffb3c into master Jun 16, 2026
9 checks passed
@tiensonqin tiensonqin deleted the refactor/ocaml-logseq-cli branch June 16, 2026 05:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants