@allansantos-dev/smart-tool 0.9.0 → 0.9.2
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.
- package/CHANGELOG.md +50 -23
- package/NOTICE +32 -32
- package/README.md +117 -116
- package/atomic_io.py +94 -94
- package/bin/smart-tool.mjs +5 -1
- package/client_hooks.py +192 -192
- package/code_graph_java.mjs +49 -49
- package/code_graph_js.cjs +135 -135
- package/duplicates.py +313 -313
- package/embedding_cache.py +99 -99
- package/endpoint_sync.py +179 -179
- package/gateway.py +220 -220
- package/hook_decision.py +96 -96
- package/index_inventory.py +75 -75
- package/indexer.py +878 -878
- package/install.py +113 -11
- package/install_runtime.py +101 -35
- package/integration_metrics.py +82 -82
- package/local_embedder.py +172 -172
- package/model_defaults.py +70 -70
- package/package.json +35 -35
- package/project_insights_ui.py +38 -38
- package/project_monitor.py +204 -204
- package/project_store.py +220 -220
- package/projects_ui.py +146 -146
- package/requirements.txt +8 -8
- package/research_cache.py +171 -171
- package/research_metrics.py +110 -110
- package/router.py +582 -582
- package/secret_store.py +121 -121
- package/setup_ui.py +1011 -986
- package/smart_tool_daemon.py +3604 -3604
- package/version.py +1 -1
- package/web_adapters/browser/fetch_camoufox.py +69 -0
- package/web_adapters/node/ddg-search.mjs +89 -89
- package/web_adapters/node/open-websearch-adapter.mjs +77 -77
- package/web_adapters/node/package.json +12 -12
- package/web_adapters/node/wikipedia-search.mjs +44 -44
- package/web_search_adapters.py +193 -193
- package/web_search_external.py +288 -288
- package/web_search_health.py +88 -88
package/index_inventory.py
CHANGED
|
@@ -1,75 +1,75 @@
|
|
|
1
|
-
"""Inventário somente leitura de visões, arquivos e trechos já persistidos."""
|
|
2
|
-
import re
|
|
3
|
-
from pathlib import Path
|
|
4
|
-
|
|
5
|
-
import indexer
|
|
6
|
-
import index_views
|
|
7
|
-
import project_identity
|
|
8
|
-
import document_text
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
def views(root):
|
|
12
|
-
key = project_identity.project_id(root)
|
|
13
|
-
current = index_views.describe(root)
|
|
14
|
-
paths = list(Path(indexer.INDEX_DIR).glob(key + '.v-*.sqlite3'))
|
|
15
|
-
paths += [Path(indexer.INDEX_DIR)/(item+'.sqlite3') for item in
|
|
16
|
-
dict.fromkeys([key, *project_identity.legacy_ids(root)])]
|
|
17
|
-
rows = []
|
|
18
|
-
for path in dict.fromkeys(paths):
|
|
19
|
-
if not path.is_file() or not re.fullmatch(r'[a-f0-9]{16}(?:\.v-[a-f0-9]{16})?\.sqlite3', path.name):
|
|
20
|
-
continue
|
|
21
|
-
conn = indexer._readonly(str(path))
|
|
22
|
-
try:
|
|
23
|
-
meta = indexer._metadata(conn)
|
|
24
|
-
view_id = meta.get('view_id') or ('legacy' if current['git'] else 'workspace')
|
|
25
|
-
rows.append({'view_id': view_id, 'label': meta.get('view_label') or 'Legacy, no identified branch',
|
|
26
|
-
'branch': meta.get('git_branch'), 'commit': meta.get('git_commit'),
|
|
27
|
-
'current': view_id == current['view_id'], 'path': str(path),
|
|
28
|
-
'files': conn.execute('SELECT count(*) FROM manifest').fetchone()[0],
|
|
29
|
-
'chunks': conn.execute('SELECT count(*) FROM chunks').fetchone()[0],
|
|
30
|
-
'model': meta.get('model_id'), 'dimensions': meta.get('dimensions'),
|
|
31
|
-
'updated_at': meta.get('updated_at'), 'bytes': path.stat().st_size})
|
|
32
|
-
finally:
|
|
33
|
-
conn.close()
|
|
34
|
-
return sorted(rows, key=lambda row: (not row['current'], row['label']))
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
def inspect(root, view_id=None, file_path=None, storage_id=None):
|
|
38
|
-
if file_path is not None:
|
|
39
|
-
if not isinstance(file_path, str):
|
|
40
|
-
raise ValueError("file_path must be a string.")
|
|
41
|
-
file_path = file_path.replace(chr(92), "/").removeprefix("./")
|
|
42
|
-
available = views(root)
|
|
43
|
-
current = index_views.describe(root)
|
|
44
|
-
explicit_view = view_id is not None or storage_id is not None
|
|
45
|
-
view_id = view_id or current['view_id']
|
|
46
|
-
selected = next((row for row in available if (Path(row['path']).name==storage_id if storage_id else row['view_id']==view_id)), None)
|
|
47
|
-
if selected is None and available and not explicit_view:
|
|
48
|
-
selected = available[0]
|
|
49
|
-
if not selected:
|
|
50
|
-
return {'views': available, 'selected': None, 'files': [], 'chunks': [],
|
|
51
|
-
'message': 'This view has not been indexed yet. Run a search or use Index now.'}
|
|
52
|
-
conn = indexer._readonly(selected['path'])
|
|
53
|
-
try:
|
|
54
|
-
columns = {row[1] for row in conn.execute('PRAGMA table_info(manifest)')}
|
|
55
|
-
# Índices anteriores ao manifest incremental não têm size/mtime_ns.
|
|
56
|
-
# A inspeção é somente leitura; não migrar nem medir o arquivo de outra branch.
|
|
57
|
-
size_column = 'm.size' if 'size' in columns else 'NULL'
|
|
58
|
-
files = [{'path': path, 'chunks': count, 'hash': digest, 'size': size} for path, count, digest, size in
|
|
59
|
-
conn.execute(f'SELECT m.path,count(c.id),m.hash,{size_column} FROM manifest m LEFT JOIN chunks c ON c.path=m.path GROUP BY m.path ORDER BY m.path LIMIT 1001')]
|
|
60
|
-
chunks = []
|
|
61
|
-
if file_path is not None:
|
|
62
|
-
if not conn.execute('SELECT 1 FROM manifest WHERE path=?', (file_path,)).fetchone():
|
|
63
|
-
raise ValueError(f'File is outside the indexed view: {file_path}')
|
|
64
|
-
files = []
|
|
65
|
-
chunks = [{'start_line': start, 'end_line': end, 'text': text, 'dimensions': int(size or 0)//4,
|
|
66
|
-
'location_kind':document_text.location_kind(file_path)}
|
|
67
|
-
for start, end, text, size in conn.execute(
|
|
68
|
-
'SELECT start_line,end_line,text,length(embedding) FROM chunks WHERE path=? ORDER BY start_line LIMIT 100', (file_path,))]
|
|
69
|
-
return {'views': available, 'selected': selected, 'files': files[:1000],
|
|
70
|
-
'truncated': len(files)>1000, 'chunks': chunks, 'max_chunks_displayed': 100,
|
|
71
|
-
'current_view': index_views.public(current),
|
|
72
|
-
'message': '' if selected['current'] else 'The current view is not shown. You are inspecting the stored index of ' + selected['label'] + '.',
|
|
73
|
-
'graph_type': 'project_branch_directory_file', 'read_only': True}
|
|
74
|
-
finally:
|
|
75
|
-
conn.close()
|
|
1
|
+
"""Inventário somente leitura de visões, arquivos e trechos já persistidos."""
|
|
2
|
+
import re
|
|
3
|
+
from pathlib import Path
|
|
4
|
+
|
|
5
|
+
import indexer
|
|
6
|
+
import index_views
|
|
7
|
+
import project_identity
|
|
8
|
+
import document_text
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
def views(root):
|
|
12
|
+
key = project_identity.project_id(root)
|
|
13
|
+
current = index_views.describe(root)
|
|
14
|
+
paths = list(Path(indexer.INDEX_DIR).glob(key + '.v-*.sqlite3'))
|
|
15
|
+
paths += [Path(indexer.INDEX_DIR)/(item+'.sqlite3') for item in
|
|
16
|
+
dict.fromkeys([key, *project_identity.legacy_ids(root)])]
|
|
17
|
+
rows = []
|
|
18
|
+
for path in dict.fromkeys(paths):
|
|
19
|
+
if not path.is_file() or not re.fullmatch(r'[a-f0-9]{16}(?:\.v-[a-f0-9]{16})?\.sqlite3', path.name):
|
|
20
|
+
continue
|
|
21
|
+
conn = indexer._readonly(str(path))
|
|
22
|
+
try:
|
|
23
|
+
meta = indexer._metadata(conn)
|
|
24
|
+
view_id = meta.get('view_id') or ('legacy' if current['git'] else 'workspace')
|
|
25
|
+
rows.append({'view_id': view_id, 'label': meta.get('view_label') or 'Legacy, no identified branch',
|
|
26
|
+
'branch': meta.get('git_branch'), 'commit': meta.get('git_commit'),
|
|
27
|
+
'current': view_id == current['view_id'], 'path': str(path),
|
|
28
|
+
'files': conn.execute('SELECT count(*) FROM manifest').fetchone()[0],
|
|
29
|
+
'chunks': conn.execute('SELECT count(*) FROM chunks').fetchone()[0],
|
|
30
|
+
'model': meta.get('model_id'), 'dimensions': meta.get('dimensions'),
|
|
31
|
+
'updated_at': meta.get('updated_at'), 'bytes': path.stat().st_size})
|
|
32
|
+
finally:
|
|
33
|
+
conn.close()
|
|
34
|
+
return sorted(rows, key=lambda row: (not row['current'], row['label']))
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
def inspect(root, view_id=None, file_path=None, storage_id=None):
|
|
38
|
+
if file_path is not None:
|
|
39
|
+
if not isinstance(file_path, str):
|
|
40
|
+
raise ValueError("file_path must be a string.")
|
|
41
|
+
file_path = file_path.replace(chr(92), "/").removeprefix("./")
|
|
42
|
+
available = views(root)
|
|
43
|
+
current = index_views.describe(root)
|
|
44
|
+
explicit_view = view_id is not None or storage_id is not None
|
|
45
|
+
view_id = view_id or current['view_id']
|
|
46
|
+
selected = next((row for row in available if (Path(row['path']).name==storage_id if storage_id else row['view_id']==view_id)), None)
|
|
47
|
+
if selected is None and available and not explicit_view:
|
|
48
|
+
selected = available[0]
|
|
49
|
+
if not selected:
|
|
50
|
+
return {'views': available, 'selected': None, 'files': [], 'chunks': [],
|
|
51
|
+
'message': 'This view has not been indexed yet. Run a search or use Index now.'}
|
|
52
|
+
conn = indexer._readonly(selected['path'])
|
|
53
|
+
try:
|
|
54
|
+
columns = {row[1] for row in conn.execute('PRAGMA table_info(manifest)')}
|
|
55
|
+
# Índices anteriores ao manifest incremental não têm size/mtime_ns.
|
|
56
|
+
# A inspeção é somente leitura; não migrar nem medir o arquivo de outra branch.
|
|
57
|
+
size_column = 'm.size' if 'size' in columns else 'NULL'
|
|
58
|
+
files = [{'path': path, 'chunks': count, 'hash': digest, 'size': size} for path, count, digest, size in
|
|
59
|
+
conn.execute(f'SELECT m.path,count(c.id),m.hash,{size_column} FROM manifest m LEFT JOIN chunks c ON c.path=m.path GROUP BY m.path ORDER BY m.path LIMIT 1001')]
|
|
60
|
+
chunks = []
|
|
61
|
+
if file_path is not None:
|
|
62
|
+
if not conn.execute('SELECT 1 FROM manifest WHERE path=?', (file_path,)).fetchone():
|
|
63
|
+
raise ValueError(f'File is outside the indexed view: {file_path}')
|
|
64
|
+
files = []
|
|
65
|
+
chunks = [{'start_line': start, 'end_line': end, 'text': text, 'dimensions': int(size or 0)//4,
|
|
66
|
+
'location_kind':document_text.location_kind(file_path)}
|
|
67
|
+
for start, end, text, size in conn.execute(
|
|
68
|
+
'SELECT start_line,end_line,text,length(embedding) FROM chunks WHERE path=? ORDER BY start_line LIMIT 100', (file_path,))]
|
|
69
|
+
return {'views': available, 'selected': selected, 'files': files[:1000],
|
|
70
|
+
'truncated': len(files)>1000, 'chunks': chunks, 'max_chunks_displayed': 100,
|
|
71
|
+
'current_view': index_views.public(current),
|
|
72
|
+
'message': '' if selected['current'] else 'The current view is not shown. You are inspecting the stored index of ' + selected['label'] + '.',
|
|
73
|
+
'graph_type': 'project_branch_directory_file', 'read_only': True}
|
|
74
|
+
finally:
|
|
75
|
+
conn.close()
|