#!/usr/bin/env bash set -euo pipefail ROOT="/mnt/Data1T/mnote" export CARGO_TARGET_DIR="${CARGO_TARGET_DIR:-/tmp/mnote-rust-target-harness}" export WORKSPACE_ID="${1:-0e0e1304-9e8d-49ad-951b-3ae93a80fc85}" STAMP="$(date +%s)" export SOURCE_PAGE_ID="cli-smoke-src-${STAMP}" export TARGET_PAGE_ID="cli-smoke-dst-${STAMP}" export MINDMAP_PAGE_ID="cli-mindmap-${STAMP}" export MINDMAP_ID="mind_cli" export TMP_DIR="${TMPDIR:-/tmp}/task049-cli-smoke-${STAMP}" mkdir -p "$TMP_DIR" export ROOT python3 - <<'PYTHON' import json import os import pathlib import subprocess import sys root = os.environ['ROOT'] workspace_id = os.environ['WORKSPACE_ID'] source_page_id = os.environ['SOURCE_PAGE_ID'] target_page_id = os.environ['TARGET_PAGE_ID'] mindmap_page_id = os.environ['MINDMAP_PAGE_ID'] mindmap_id = os.environ['MINDMAP_ID'] tmp_dir = pathlib.Path(os.environ['TMP_DIR']) cargo = [ 'cargo', 'run', '--manifest-path', f'{root}/rust/Cargo.toml', '-p', 'mnote-cli', '--', ] env = os.environ.copy() def run(name: str, *args: str) -> dict: cmd = cargo + ['--json', '--execute', *args] cp = subprocess.run(cmd, cwd=root, env=env, text=True, capture_output=True) (tmp_dir / f'{name}.stdout').write_text(cp.stdout, encoding='utf-8') (tmp_dir / f'{name}.stderr').write_text(cp.stderr, encoding='utf-8') if cp.returncode != 0: raise SystemExit(f'command failed {name}: {cp.stderr}') data = json.loads(cp.stdout) (tmp_dir / f'{name}.json').write_text( json.dumps(data, ensure_ascii=False, indent=2), encoding='utf-8', ) if not data.get('ok', False): raise SystemExit(f'command returned ok=false {name}: {cp.stdout}') return data sidebar_dataset = run('01-sidebar-dataset', 'sidebar', 'dataset', '--workspace-id', workspace_id) create_src = run( '02-page-create-src', 'page', 'create', '--page-id', source_page_id, '--workspace-id', workspace_id, '--title', f'CLI Verify SRC {source_page_id}', '--content-json', '[{"id":"init_block","type":"paragraph","content":[{"type":"text","text":"source init"}],"children":[]}]', ) create_dst = run( '03-page-create-dst', 'page', 'create', '--page-id', target_page_id, '--workspace-id', workspace_id, '--title', f'CLI Verify DST {target_page_id}', '--content-json', '[]', ) page_get = run('04-page-get', 'page', 'get', '--page-id', source_page_id, '--workspace-id', workspace_id) page_title = run( '05-page-title', 'page', 'title', '--page-id', source_page_id, '--workspace-id', workspace_id, '--title', f'CLI Verify {source_page_id} Renamed', ) page_save = run( '06-page-save', 'page', 'save', '--page-id', source_page_id, '--workspace-id', workspace_id, '--revision', '0', '--conflict-detection-key', f'{source_page_id}:0', '--content-json', '[{"id":"init_block","type":"paragraph","content":[{"type":"text","text":"source saved"}],"children":[]}]', ) block_insert = run( '07-block-insert', 'block', 'insert', '--workspace-id', workspace_id, '--page-id', source_page_id, '--content', 'move me', '--block-type', 'paragraph', ) inserted_block_id = block_insert['operation']['execution']['inserted'][0] block_patch = run( '08-block-patch', 'block', 'patch', '--page-id', source_page_id, '--workspace-id', workspace_id, '--block-id', 'init_block', '--revision', '2', '--conflict-detection-key', f'{source_page_id}:2', '--snapshot-json', '{"id":"init_block","type":"paragraph","content":[{"type":"text","text":"source patched"}],"children":[]}', ) source_after_patch = run( '09-page-get-after-patch', 'page', 'get', '--page-id', source_page_id, '--workspace-id', workspace_id, ) block_move = run( '10-block-move', 'block', 'move', '--source-document-id', source_page_id, '--block-id', inserted_block_id, '--target-document-id', target_page_id, ) block_embed = run( '11-block-embed', 'block', 'embed', '--source-document-id', source_page_id, '--block-id', 'init_block', '--target-document-id', target_page_id, ) page_move = run( '12-page-move', 'page', 'move', '--page-id', target_page_id, '--workspace-id', workspace_id, '--parent-id', source_page_id, '--sort-order', '2', ) search_documents = run( '13-search-documents', 'search', 'documents', '--workspace-id', workspace_id, '--query', source_page_id, ) tool_docs_search = run( '14-tool-docs-search', 'tool', 'run', '--tool-name', 'docs_search', '--kind', 'query', '--mode', 'result', '--args-json', json.dumps({'query': source_page_id, 'workspaceId': workspace_id, 'limit': 5}, ensure_ascii=False), ) tool_docs_read = run( '15-tool-docs-read', 'tool', 'run', '--tool-name', 'docs_read', '--kind', 'query', '--mode', 'result', '--args-json', json.dumps({'documentId': source_page_id, 'includeContent': True, 'maxChars': 1000}, ensure_ascii=False), ) page_delete = run('16-page-delete-target', 'page', 'delete', '--page-id', target_page_id, '--workspace-id', workspace_id) page_restore = run('17-page-restore-target', 'page', 'restore', '--page-id', target_page_id, '--workspace-id', workspace_id) page_get_restored = run('18-page-get-restored-target', 'page', 'get', '--page-id', target_page_id, '--workspace-id', workspace_id) final_delete_target = run('19-page-delete-target-final', 'page', 'delete', '--page-id', target_page_id, '--workspace-id', workspace_id) create_mindmap_page = run( '20-page-create-mindmap', 'page', 'create', '--page-id', mindmap_page_id, '--workspace-id', workspace_id, '--title', f'CLI Mindmap {mindmap_page_id}', '--content-json', '[]', ) mindmap_put = run( '21-mindmap-put', 'mindmap', 'put', '--document-id', mindmap_page_id, '--mindmap-id', mindmap_id, '--workspace-id', workspace_id, '--data-json', '{"data":{"uid":"root_1","text":"中心主题"},"children":[]}', '--create-only', ) mindmap_get = run( '22-mindmap-get', 'mindmap', 'get', '--document-id', mindmap_page_id, '--mindmap-id', mindmap_id, '--workspace-id', workspace_id, ) mindmap_op = run( '23-mindmap-op', 'mindmap', 'op', '--document-id', mindmap_page_id, '--mindmap-id', mindmap_id, '--workspace-id', workspace_id, '--ops-json', '[{"op":"addChild","parentUid":"root_1","node":{"text":"新分支"}}]', ) final_delete_source = run('24-page-delete-source-final', 'page', 'delete', '--page-id', source_page_id, '--workspace-id', workspace_id) final_delete_mindmap_page = run('25-page-delete-mindmap-final', 'page', 'delete', '--page-id', mindmap_page_id, '--workspace-id', workspace_id) summary = { 'workspaceId': workspace_id, 'sourcePageId': source_page_id, 'targetPageId': target_page_id, 'mindmapPageId': mindmap_page_id, 'insertedBlockId': inserted_block_id, 'sidebarDocuments': len(sidebar_dataset['operation']['execution'].get('documents', [])), 'pageGetRevision': page_get['operation']['execution'].get('revision'), 'pageTitleUpdatedAt': page_title['operation']['execution'].get('updated_at'), 'pageSaveRevision': page_save['operation']['execution'].get('revision'), 'sourceAfterPatchBlocks': len(source_after_patch['operation']['execution'].get('content', [])), 'blockPatchRevision': block_patch['operation']['execution'].get('revision'), 'blockMoveExecution': block_move['operation']['execution'], 'blockEmbedExecution': block_embed['operation']['execution'], 'pageMoveExecution': page_move['operation']['execution'], 'searchResults': len(search_documents['operation']['execution'].get('results', [])), 'toolDocsSearchResults': len(tool_docs_search['operation']['execution'].get('results', [])), 'toolDocsReadRawTextLength': tool_docs_read['operation']['execution'].get('rawTextLength'), 'pageRestoreExecution': page_restore['operation']['execution'], 'restoredTargetBlocks': len(page_get_restored['operation']['execution'].get('content', [])), 'mindmapPutExecution': mindmap_put['operation']['execution'], 'mindmapGetExists': mindmap_get['operation']['execution'].get('meta', {}).get('exists'), 'mindmapOpExecution': mindmap_op['operation']['execution'], 'cleanup': { 'targetDeleted': final_delete_target['operation']['execution'].get('ok'), 'sourceDeleted': final_delete_source['operation']['execution'].get('ok'), 'mindmapPageDeleted': final_delete_mindmap_page['operation']['execution'].get('ok'), }, 'tmpDir': str(tmp_dir), } print(json.dumps(summary, ensure_ascii=False, indent=2)) PYTHON echo "task049-cli-smoke ok workspace_id=$WORKSPACE_ID source_page_id=$SOURCE_PAGE_ID target_page_id=$TARGET_PAGE_ID mindmap_page_id=$MINDMAP_PAGE_ID tmp_dir=$TMP_DIR"