wp2txt 2.3.2 → 2.3.3
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.
- checksums.yaml +4 -4
- data/.dockerignore +3 -0
- data/.github/workflows/publish-image.yml +140 -0
- data/CHANGELOG.md +14 -0
- data/DEVELOPMENT.md +12 -4
- data/DEVELOPMENT_ja.md +2 -3
- data/README.md +1 -1
- data/README_ja.md +1 -1
- data/Rakefile +22 -16
- data/bin/wp2txt +4 -2
- data/bin/wp2txt-mcp +4 -3
- data/docs/INDEXES.md +4 -0
- data/lib/wp2txt/constants.rb +5 -0
- data/lib/wp2txt/corpus.rb +96 -79
- data/lib/wp2txt/corpus_jobs.rb +15 -13
- data/lib/wp2txt/fts_index.rb +12 -3
- data/lib/wp2txt/metadata_index.rb +3 -3
- data/lib/wp2txt/output_path.rb +72 -12
- data/lib/wp2txt/stream_processor.rb +19 -9
- data/lib/wp2txt/version.rb +1 -1
- data/spec/fts_index_spec.rb +40 -0
- data/spec/p1_correctness_spec.rb +357 -0
- data/spec/stream_processor_spec.rb +3 -1
- data/spec/titles_output_path_spec.rb +49 -1
- data/wp2txt.gemspec +1 -1
- metadata +4 -9
- data/image/wp2txt-logo.svg +0 -16
- data/image/wp2txt.svg +0 -31
- data/scripts/benchmark_regex.rb +0 -161
- data/scripts/fetch_html_entities.rb +0 -94
- data/scripts/fetch_language_metadata.rb +0 -180
- data/scripts/fetch_mediawiki_data.rb +0 -334
- data/scripts/fetch_template_data.rb +0 -186
- data/scripts/profile_memory.rb +0 -139
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 051b5501ecf2aad35ca972af6527c5afbce88222c17e9c93dc76f806b91a8e9d
|
|
4
|
+
data.tar.gz: 02efabb7102da40c144a3c8204f564a8a40dfa1e77a54813e40bd6740693a264
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: d89ff3e231200c36f647284fee43565021c69c73ac8d9f23ca42b58008d2d0d3ac5598fe63aa3736a45ce933622dd28f649f721635a63e782d638f444602d08b
|
|
7
|
+
data.tar.gz: c70fccdb332688f805e77dbefd291563045e2f53c07e7cc994dbff0a7f8858dded28f18bce4bcb1296e7594f12ee54eea12a4573beee04a8944d4e39b7d35620
|
data/.dockerignore
CHANGED
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
name: Publish image
|
|
2
|
+
|
|
3
|
+
# Publishes the multi-arch container image to the GitHub Container Registry.
|
|
4
|
+
#
|
|
5
|
+
# Publishing happens here rather than from a maintainer's machine on purpose. A
|
|
6
|
+
# local build sends the working tree as the build context, so anything sitting
|
|
7
|
+
# there untracked rides along; a runner starts from a clean checkout, where such
|
|
8
|
+
# files do not exist. Twice, private files reached published images this way.
|
|
9
|
+
#
|
|
10
|
+
# Fires on a v* tag. Run it by hand from the Actions tab for a dry run: the
|
|
11
|
+
# default leaves `push` off, so it builds and gates without publishing.
|
|
12
|
+
|
|
13
|
+
on:
|
|
14
|
+
push:
|
|
15
|
+
tags: ['v*']
|
|
16
|
+
workflow_dispatch:
|
|
17
|
+
inputs:
|
|
18
|
+
push:
|
|
19
|
+
description: 'Publish to GHCR (off = build and gate only)'
|
|
20
|
+
type: boolean
|
|
21
|
+
default: false
|
|
22
|
+
|
|
23
|
+
env:
|
|
24
|
+
IMAGE: ghcr.io/yohasebe/wp2txt
|
|
25
|
+
|
|
26
|
+
jobs:
|
|
27
|
+
publish:
|
|
28
|
+
name: Build, gate, publish
|
|
29
|
+
runs-on: ubuntu-latest
|
|
30
|
+
permissions:
|
|
31
|
+
contents: read
|
|
32
|
+
packages: write
|
|
33
|
+
|
|
34
|
+
steps:
|
|
35
|
+
- uses: actions/checkout@v4
|
|
36
|
+
|
|
37
|
+
- name: Work out the version and whether to publish
|
|
38
|
+
id: plan
|
|
39
|
+
run: |
|
|
40
|
+
set -euo pipefail
|
|
41
|
+
file_version=$(grep -oE '[0-9]+\.[0-9]+\.[0-9]+' lib/wp2txt/version.rb | head -1)
|
|
42
|
+
if [ -z "$file_version" ]; then
|
|
43
|
+
echo "could not read a version from lib/wp2txt/version.rb" >&2
|
|
44
|
+
exit 1
|
|
45
|
+
fi
|
|
46
|
+
|
|
47
|
+
if [ "${GITHUB_EVENT_NAME}" = "push" ]; then
|
|
48
|
+
tag_version="${GITHUB_REF_NAME#v}"
|
|
49
|
+
if [ "$tag_version" != "$file_version" ]; then
|
|
50
|
+
echo "tag ${GITHUB_REF_NAME} disagrees with lib/wp2txt/version.rb (${file_version})" >&2
|
|
51
|
+
echo "Publishing would tag the image with a version the code does not claim." >&2
|
|
52
|
+
exit 1
|
|
53
|
+
fi
|
|
54
|
+
publish=true
|
|
55
|
+
else
|
|
56
|
+
publish="${{ inputs.push }}"
|
|
57
|
+
fi
|
|
58
|
+
|
|
59
|
+
echo "version=$file_version" >> "$GITHUB_OUTPUT"
|
|
60
|
+
echo "publish=$publish" >> "$GITHUB_OUTPUT"
|
|
61
|
+
echo "Version $file_version; publish=$publish"
|
|
62
|
+
|
|
63
|
+
- uses: ruby/setup-ruby@v1
|
|
64
|
+
with:
|
|
65
|
+
ruby-version: '3.3'
|
|
66
|
+
|
|
67
|
+
- uses: docker/setup-qemu-action@v3
|
|
68
|
+
|
|
69
|
+
- uses: docker/setup-buildx-action@v3
|
|
70
|
+
|
|
71
|
+
# Single arch, loaded into the daemon, so the gate can open it. The
|
|
72
|
+
# multi-arch build below reuses these layers from the builder's cache.
|
|
73
|
+
- name: Build for inspection (linux/amd64)
|
|
74
|
+
uses: docker/build-push-action@v6
|
|
75
|
+
with:
|
|
76
|
+
context: .
|
|
77
|
+
platforms: linux/amd64
|
|
78
|
+
load: true
|
|
79
|
+
push: false
|
|
80
|
+
tags: ${{ env.IMAGE }}:gate-candidate
|
|
81
|
+
|
|
82
|
+
- name: Gate — compare the image against the build context
|
|
83
|
+
run: ruby scripts/verify_image.rb "${IMAGE}:gate-candidate"
|
|
84
|
+
|
|
85
|
+
- name: Log in to GHCR
|
|
86
|
+
if: steps.plan.outputs.publish == 'true'
|
|
87
|
+
uses: docker/login-action@v3
|
|
88
|
+
with:
|
|
89
|
+
registry: ghcr.io
|
|
90
|
+
username: ${{ github.actor }}
|
|
91
|
+
password: ${{ secrets.GITHUB_TOKEN }}
|
|
92
|
+
|
|
93
|
+
- name: Build and push (linux/amd64, linux/arm64)
|
|
94
|
+
id: publish
|
|
95
|
+
if: steps.plan.outputs.publish == 'true'
|
|
96
|
+
uses: docker/build-push-action@v6
|
|
97
|
+
with:
|
|
98
|
+
context: .
|
|
99
|
+
platforms: linux/amd64,linux/arm64
|
|
100
|
+
push: true
|
|
101
|
+
tags: |
|
|
102
|
+
${{ env.IMAGE }}:${{ steps.plan.outputs.version }}
|
|
103
|
+
${{ env.IMAGE }}:latest
|
|
104
|
+
labels: |
|
|
105
|
+
org.opencontainers.image.source=https://github.com/yohasebe/wp2txt
|
|
106
|
+
org.opencontainers.image.version=${{ steps.plan.outputs.version }}
|
|
107
|
+
|
|
108
|
+
# Reading it back without credentials is the only proof that a user can
|
|
109
|
+
# pull what was just published.
|
|
110
|
+
- name: Check the published digest is readable anonymously
|
|
111
|
+
if: steps.plan.outputs.publish == 'true'
|
|
112
|
+
run: |
|
|
113
|
+
set -euo pipefail
|
|
114
|
+
digest="${{ steps.publish.outputs.digest }}"
|
|
115
|
+
docker logout ghcr.io
|
|
116
|
+
for attempt in 1 2 3 4 5; do
|
|
117
|
+
if docker manifest inspect "${IMAGE}@${digest}" > /dev/null 2>&1; then
|
|
118
|
+
echo "readable anonymously: ${IMAGE}@${digest}"
|
|
119
|
+
exit 0
|
|
120
|
+
fi
|
|
121
|
+
echo "attempt ${attempt} failed; ghcr.io can lag a few seconds, retrying in 10s"
|
|
122
|
+
sleep 10
|
|
123
|
+
done
|
|
124
|
+
echo "${IMAGE}@${digest} is not readable anonymously" >&2
|
|
125
|
+
exit 1
|
|
126
|
+
|
|
127
|
+
- name: Summary
|
|
128
|
+
if: always()
|
|
129
|
+
run: |
|
|
130
|
+
{
|
|
131
|
+
echo "### wp2txt image"
|
|
132
|
+
echo
|
|
133
|
+
echo "- version: \`${{ steps.plan.outputs.version }}\`"
|
|
134
|
+
echo "- published: \`${{ steps.plan.outputs.publish }}\`"
|
|
135
|
+
if [ -n "${{ steps.publish.outputs.digest }}" ]; then
|
|
136
|
+
echo "- digest: \`${{ steps.publish.outputs.digest }}\`"
|
|
137
|
+
echo "- pull: \`docker pull ${IMAGE}:${{ steps.plan.outputs.version }}\`"
|
|
138
|
+
fi
|
|
139
|
+
echo "- run: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}"
|
|
140
|
+
} >> "$GITHUB_STEP_SUMMARY"
|
data/CHANGELOG.md
CHANGED
|
@@ -8,6 +8,20 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
8
8
|
Entries were rewritten in August 2026 to describe what changed for people using
|
|
9
9
|
wp2txt, rather than how it was implemented. The changes themselves are unaltered.
|
|
10
10
|
|
|
11
|
+
## [2.3.3] - 2026-09-08
|
|
12
|
+
|
|
13
|
+
- **Short searches no longer report a false zero**: in Japanese, Chinese, and Korean indexes a phrase of one or two characters could match nothing and come back as `0 matches`, which reads exactly like a term that is genuinely absent from the dump. Such a search now fails with an explicit error instead. If you recorded a zero result for a short term with an earlier version, re-check it
|
|
14
|
+
- **Characters no longer vanish from extracted text**: a multi-byte character that happened to straddle an internal read boundary was dropped, silently and at unpredictable positions. Any non-ASCII text could be affected. Re-extract if you need the output to be exact
|
|
15
|
+
- **Articles whose title contains a colon are no longer skipped**: `Star Trek: Voyager` and titles like it were mistaken for administrative pages and left out of both extraction and indexes. Rebuild with `--build-index -U` and re-extract to pick them up
|
|
16
|
+
- **`query_sql` no longer loses values when column names repeat**: a query selecting two columns under the same name kept only one of them. Names are now made unique, and the `.meta.json` beside a file result records which output name corresponds to which column of your query
|
|
17
|
+
- **Cell clipping counts bytes, not characters**: a long cell was measured in characters, so it could exceed the limit and still be reported as unclipped — 30,000 Japanese characters are 90,000 bytes. The limit is now 65,536 bytes, cut at a character boundary, and the count of clipped cells is accurate
|
|
18
|
+
- **A result of exactly the requested size is no longer marked truncated**: `truncated` came back true when a result happened to fill the limit exactly, with nothing left behind
|
|
19
|
+
- **Output files stay inside the output directory**: a symbolic link within it could redirect a write outside, the `.meta.json` sidecar was not checked at all, and an existing file could slip past `overwrite: false`. Output and sidecar are now reserved together and written to a temporary file first, so a failed or cancelled run leaves your previous output untouched instead of a half-written file in its place
|
|
20
|
+
- **Index builds no longer grow in memory with the size of the dump**: every batch of extracted text was kept until the build finished
|
|
21
|
+
- **A background job that fails to start is now reported as failed**: it stayed `running` indefinitely and blocked every later job until the server was restarted
|
|
22
|
+
- **The gem no longer ships maintainer scripts or images**. If you were running `scripts/fetch_*.rb` from an installed gem, take them from the repository instead
|
|
23
|
+
- **The Docker Hub repository has been removed**: images are published to GitHub Container Registry only. If you still pull from Docker Hub, switch with `docker pull ghcr.io/yohasebe/wp2txt`
|
|
24
|
+
|
|
11
25
|
## [2.3.2] - 2026-08-13
|
|
12
26
|
|
|
13
27
|
- **Documentation release — no code changes.** The changelog and guides bundled with the gem and the container image are rewritten to say what each change means for someone using wp2txt, rather than how it was implemented. The guide formerly at `docs/RESEARCH.md` is now [docs/INDEXES.md](docs/INDEXES.md) ("Offline Indexes, Queries, and the MCP Server")
|
data/DEVELOPMENT.md
CHANGED
|
@@ -400,13 +400,21 @@ docs/INDEXES.md is checked against the actual server surface by spec/docs_sync_s
|
|
|
400
400
|
|
|
401
401
|
## Docker
|
|
402
402
|
|
|
403
|
-
|
|
403
|
+
Images are published by GitHub Actions when a `v*` tag is pushed
|
|
404
|
+
(`.github/workflows/publish-image.yml`), not from a maintainer's machine: a
|
|
405
|
+
local build sends the working tree as its context, so untracked files ride
|
|
406
|
+
along, while a runner starts from a clean checkout.
|
|
404
407
|
|
|
405
408
|
```bash
|
|
406
|
-
rake check_image
|
|
407
|
-
rake push # Verifies, then builds multi-arch and pushes to GHCR
|
|
409
|
+
rake check_image # Build locally and run the same gate the workflow runs
|
|
408
410
|
```
|
|
409
411
|
|
|
412
|
+
The gate (`scripts/verify_image.rb`) lists what the image holds under `/wp2txt`
|
|
413
|
+
and compares it against what Docker sends as the build context, in both
|
|
414
|
+
directions. Anything unaccounted for fails, so a file the build starts
|
|
415
|
+
producing must be added to `BUILD_ARTIFACTS` deliberately. To rehearse a
|
|
416
|
+
publish, run the workflow from the Actions tab with **push** left off.
|
|
417
|
+
|
|
410
418
|
## Release Process
|
|
411
419
|
|
|
412
420
|
1. Update version in `lib/wp2txt/version.rb`
|
|
@@ -414,7 +422,7 @@ rake push # Verifies, then builds multi-arch and pushes to GHCR
|
|
|
414
422
|
3. Run full test suite: `bundle exec rspec`
|
|
415
423
|
4. Build gem: `gem build wp2txt.gemspec`
|
|
416
424
|
5. Push to RubyGems: `gem push wp2txt-*.gem`
|
|
417
|
-
6. Push
|
|
425
|
+
6. Push the `v*` tag — GitHub Actions builds, gates, and publishes the image
|
|
418
426
|
7. Create GitHub release
|
|
419
427
|
|
|
420
428
|
## Useful Links
|
data/DEVELOPMENT_ja.md
CHANGED
|
@@ -402,8 +402,7 @@ docs/INDEXES.md の MCP ツール表は spec/docs_sync_spec.rb が実際のサ
|
|
|
402
402
|
Dockerイメージのビルドとプッシュ:
|
|
403
403
|
|
|
404
404
|
```bash
|
|
405
|
-
rake check_image
|
|
406
|
-
rake push # 検証したうえでマルチアーキテクチャでビルドしGHCRにプッシュ
|
|
405
|
+
rake check_image # ローカルでビルドし、CI と同じゲートを走らせる
|
|
407
406
|
```
|
|
408
407
|
|
|
409
408
|
## リリースプロセス
|
|
@@ -413,7 +412,7 @@ rake push # 検証したうえでマルチアーキテクチャでビル
|
|
|
413
412
|
3. フルテストスイートを実行: `bundle exec rspec`
|
|
414
413
|
4. gemをビルド: `gem build wp2txt.gemspec`
|
|
415
414
|
5. RubyGemsにプッシュ: `gem push wp2txt-*.gem`
|
|
416
|
-
6.
|
|
415
|
+
6. `v*` タグをプッシュ — GitHub Actions がビルド・検証・公開を行う
|
|
417
416
|
7. GitHubリリースを作成
|
|
418
417
|
|
|
419
418
|
## 便利なリンク
|
data/README.md
CHANGED
|
@@ -84,7 +84,7 @@ docker run -it -v /path/to/localdata:/data ghcr.io/yohasebe/wp2txt
|
|
|
84
84
|
|
|
85
85
|
The `wp2txt` command is available inside the container. Use `/data` for input/output files.
|
|
86
86
|
|
|
87
|
-
Images are published to GitHub Container Registry (`ghcr.io/yohasebe/wp2txt`). The former Docker Hub repository
|
|
87
|
+
Images are published to GitHub Container Registry (`ghcr.io/yohasebe/wp2txt`). The former Docker Hub repository has been removed — pull from GHCR.
|
|
88
88
|
|
|
89
89
|
**MCP server (no Ruby required on the host):**
|
|
90
90
|
|
data/README_ja.md
CHANGED
|
@@ -80,7 +80,7 @@ docker run -it -v /path/to/localdata:/data ghcr.io/yohasebe/wp2txt
|
|
|
80
80
|
|
|
81
81
|
`wp2txt`コマンドはコンテナ内で使用可能です。入出力には`/data`ディレクトリを使用してください。
|
|
82
82
|
|
|
83
|
-
イメージはGitHub Container Registry(`ghcr.io/yohasebe/wp2txt`)で公開されています。旧 Docker Hub
|
|
83
|
+
イメージはGitHub Container Registry(`ghcr.io/yohasebe/wp2txt`)で公開されています。旧 Docker Hub リポジトリは削除済みです — GHCR から pull してください。
|
|
84
84
|
|
|
85
85
|
## 基本的な使い方
|
|
86
86
|
|
data/Rakefile
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
require "bundler/gem_tasks"
|
|
4
|
+
require "open3"
|
|
4
5
|
require "rspec/core"
|
|
5
6
|
require "rspec/core/rake_task"
|
|
6
7
|
require_relative "./lib/wp2txt/version"
|
|
@@ -28,6 +29,10 @@ end
|
|
|
28
29
|
|
|
29
30
|
Rake::Task["build"].enhance([:normalize_permissions])
|
|
30
31
|
|
|
32
|
+
# Pre-release gate: verify the built gem's payload against spec.files and scan
|
|
33
|
+
# it for names, content, and modes that must never ship (code-security protocol).
|
|
34
|
+
Rake::Task["build"].enhance { sh "ruby", "scripts/verify_gem.rb" }
|
|
35
|
+
|
|
31
36
|
# =============================================================================
|
|
32
37
|
# Docker
|
|
33
38
|
# =============================================================================
|
|
@@ -35,13 +40,14 @@ Rake::Task["build"].enhance([:normalize_permissions])
|
|
|
35
40
|
# Paths that must never reach a published image. The image is built from the
|
|
36
41
|
# working tree, so anything ignored locally (private notes, scratch files)
|
|
37
42
|
# would otherwise ride along.
|
|
38
|
-
IMAGE_FORBIDDEN_PATHS = %w[/wp2txt/research-notes /wp2txt/tmp /wp2txt/.git /wp2txt/CLAUDE.md /wp2txt/.claude].freeze
|
|
43
|
+
IMAGE_FORBIDDEN_PATHS = %w[/wp2txt/research-notes /wp2txt/tmp /wp2txt/.git /wp2txt/CLAUDE.md /wp2txt/.claude /wp2txt/.private-doc-tokens].freeze
|
|
39
44
|
|
|
40
45
|
desc "Verify a built image contains no private material (run before pushing)"
|
|
41
46
|
task :verify_image, [:tag] do |_t, args|
|
|
42
47
|
tag = args[:tag] || "wp2txt-verify:local"
|
|
43
48
|
checks = IMAGE_FORBIDDEN_PATHS.map { |p| "test -e #{p} && echo LEAK:#{p}" }.join("; ")
|
|
44
|
-
out =
|
|
49
|
+
out, status = Open3.capture2e("docker", "run", "--rm", tag, "sh", "-c", "#{checks}; true")
|
|
50
|
+
abort "Image verification failed for #{tag}: #{out}" unless status.success?
|
|
45
51
|
leaks = out.lines.grep(/^LEAK:/).map(&:strip)
|
|
46
52
|
abort "Image #{tag} contains private paths:\n #{leaks.join("\n ")}" unless leaks.empty?
|
|
47
53
|
|
|
@@ -54,18 +60,18 @@ task :check_image do
|
|
|
54
60
|
Rake::Task[:verify_image].invoke
|
|
55
61
|
end
|
|
56
62
|
|
|
57
|
-
desc "
|
|
58
|
-
task push
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
63
|
+
desc "Explain how images are published (they are built and pushed by CI)"
|
|
64
|
+
task :push do
|
|
65
|
+
abort <<~MESSAGE
|
|
66
|
+
Images are published by GitHub Actions, not from here.
|
|
67
|
+
|
|
68
|
+
A local build sends this working tree as the build context, so untracked
|
|
69
|
+
files ride along; a runner starts from a clean checkout, where they do not
|
|
70
|
+
exist. Push a v* tag and .github/workflows/publish-image.yml takes over:
|
|
71
|
+
|
|
72
|
+
rake release # tags and pushes (also publishes the gem)
|
|
73
|
+
|
|
74
|
+
To rehearse without publishing, run the workflow from the Actions tab with
|
|
75
|
+
"push" left off. To check a local build, run `rake check_image`.
|
|
76
|
+
MESSAGE
|
|
71
77
|
end
|
data/bin/wp2txt
CHANGED
|
@@ -217,7 +217,8 @@ class WpApp
|
|
|
217
217
|
next unless title_match
|
|
218
218
|
|
|
219
219
|
title = title_match[1]
|
|
220
|
-
next if title.nil? || title.empty?
|
|
220
|
+
next if title.nil? || title.empty?
|
|
221
|
+
next unless Wp2txt.namespace_id(page_xml[%r{<ns>(-?\d+)</ns>}, 1]).zero?
|
|
221
222
|
|
|
222
223
|
# Extract text content
|
|
223
224
|
text_match = TEXT_REGEX.match(page_xml)
|
|
@@ -609,7 +610,8 @@ class WpApp
|
|
|
609
610
|
next unless title_match
|
|
610
611
|
|
|
611
612
|
title = title_match[1]
|
|
612
|
-
next if title.nil? || title.empty?
|
|
613
|
+
next if title.nil? || title.empty?
|
|
614
|
+
next unless Wp2txt.namespace_id(page_xml[%r{<ns>(-?\d+)</ns>}, 1]).zero?
|
|
613
615
|
|
|
614
616
|
text_match = TEXT_REGEX.match(page_xml)
|
|
615
617
|
next unless text_match
|
data/bin/wp2txt-mcp
CHANGED
|
@@ -73,7 +73,7 @@ def respond(&block)
|
|
|
73
73
|
result = block.call
|
|
74
74
|
MCP::Tool::Response.new([{ type: "text", text: JSON.generate(result) }])
|
|
75
75
|
rescue ArgumentError => e
|
|
76
|
-
MCP::Tool::Response.new([{ type: "text", text: JSON.generate({ error: e.message }) }], error: true)
|
|
76
|
+
MCP::Tool::Response.new([{ type: "text", text: JSON.generate({ error: e.message, code: (e.code if e.respond_to?(:code)) }.compact) }], error: true)
|
|
77
77
|
rescue StandardError => e
|
|
78
78
|
MCP::Tool::Response.new([{ type: "text", text: JSON.generate({ error: "#{e.class}: #{e.message}" }) }], error: true)
|
|
79
79
|
end
|
|
@@ -312,7 +312,8 @@ def extract_params(output_path:, content:, titles: nil, sections: nil, alias_set
|
|
|
312
312
|
content: content, titles: titles,
|
|
313
313
|
sections: sections, alias_set: alias_set, category: category, depth: depth,
|
|
314
314
|
categories: categories, category_match: category_match,
|
|
315
|
-
title_match: title_match, limit: limit, chunk_size: chunk_size, chunk_overlap: chunk_overlap
|
|
315
|
+
title_match: title_match, limit: limit, chunk_size: chunk_size, chunk_overlap: chunk_overlap,
|
|
316
|
+
overwrite: overwrite }
|
|
316
317
|
end
|
|
317
318
|
|
|
318
319
|
server.define_tool(
|
|
@@ -341,7 +342,7 @@ end
|
|
|
341
342
|
|
|
342
343
|
server.define_tool(
|
|
343
344
|
name: "cancel_job",
|
|
344
|
-
description: "Request cancellation of a running job (takes effect at the next batch boundary;
|
|
345
|
+
description: "Request cancellation of a running job (takes effect at the next batch boundary; staged output is removed).",
|
|
345
346
|
input_schema: { properties: { job_id: { type: "string" } }, required: ["job_id"] }
|
|
346
347
|
) do |job_id:, server_context:|
|
|
347
348
|
respond { job_manager.cancel(job_id) || { error: "unknown job: #{job_id}" } }
|
data/docs/INDEXES.md
CHANGED
|
@@ -130,6 +130,10 @@ $ claude mcp add wp2txt -- docker run -i --rm -v wp2txt:/root/.wp2txt ghcr.io/yo
|
|
|
130
130
|
seconds, saved alias sets are re-checked before being stored, and files can only be
|
|
131
131
|
written under the server's output directory — worth knowing if you plan to let an
|
|
132
132
|
assistant work unattended.
|
|
133
|
+
Output confinement assumes a dedicated, trusted output directory: symlink paths are
|
|
134
|
+
rejected, both output and sidecar are exclusively reserved unless overwrite is requested,
|
|
135
|
+
and unique temporary files are renamed on success; concurrent replacement of parent
|
|
136
|
+
directories is outside this guarantee.
|
|
133
137
|
|
|
134
138
|
## 5. Cross-language SQL
|
|
135
139
|
|
data/lib/wp2txt/constants.rb
CHANGED
|
@@ -1,6 +1,11 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
module Wp2txt
|
|
4
|
+
# Missing namespace elements use the metadata scanner's historical ns=0 default.
|
|
5
|
+
def self.namespace_id(value)
|
|
6
|
+
(value || "0").to_i
|
|
7
|
+
end
|
|
8
|
+
|
|
4
9
|
# =========================================================================
|
|
5
10
|
# Custom Exception Classes
|
|
6
11
|
# =========================================================================
|