Skip to content

Commit f566a6f

Browse files
committed
feat: harden exports and slim offline app shell
1 parent 531e25d commit f566a6f

57 files changed

Lines changed: 4124 additions & 578 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/ci.yml

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
name: CI
2+
3+
on:
4+
push:
5+
branches:
6+
- main
7+
pull_request:
8+
9+
jobs:
10+
test-and-build:
11+
runs-on: ubuntu-latest
12+
13+
defaults:
14+
run:
15+
working-directory: structure-insight
16+
17+
steps:
18+
- name: Checkout
19+
uses: actions/checkout@v4
20+
21+
- name: Setup Node.js
22+
uses: actions/setup-node@v4
23+
with:
24+
node-version: 22
25+
cache: npm
26+
cache-dependency-path: structure-insight/package-lock.json
27+
28+
- name: Install dependencies
29+
run: npm ci
30+
31+
- name: Typecheck
32+
run: npm run typecheck
33+
34+
- name: Test
35+
run: npm test -- --run
36+
37+
- name: Build
38+
run: npm run build

README.md

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66

77
**一个强大的浏览器端工具,用于快速分析和可视化任何代码项目的文件结构和内容。旨在帮助开发人员生成格式化的输出,便于与 AI 语言模型共享和讨论代码。**
88

9+
> 仓库说明:实际前端应用位于 `structure-insight/` 子目录。开发、测试和构建命令都应在该目录下运行。
10+
911
---
1012

1113
### [**🚀 在线体验 »**](https://structure-insight-website.pages.dev/)
@@ -71,10 +73,18 @@
7173

7274
您可以轻松地在本地运行此项目。
7375

76+
### 仓库结构
77+
78+
- `README.md`: 仓库入口说明
79+
- `structure-insight/`: Vite + React 应用源码
80+
- `structure-insight/public/`: PWA 资源与静态文件
81+
- `.github/workflows/ci.yml`: 持续集成配置
82+
7483
**1. 克隆仓库**
7584
```bash
7685
git clone https://github.com/yeahhe365/Structure-Insight.git
7786
cd Structure-Insight
87+
cd structure-insight
7888
```
7989

8090
**2. 安装依赖**
@@ -88,6 +98,15 @@ npm run dev
8898
```
8999
应用将在 `http://localhost:5173` (或其他可用端口) 上启动。
90100

101+
### 常用脚本
102+
103+
```bash
104+
npm run typecheck
105+
npm test -- --run
106+
npm run build
107+
npm run check
108+
```
109+
91110
## 🤝 贡献 (Contributing)
92111

93112
欢迎各种形式的贡献!如果您有功能建议、发现错误或希望改进代码,请随时:

structure-insight/App.tsx

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ const SettingsDialog = React.lazy(() => import('./components/SettingsDialog'));
1313
const SearchDialog = React.lazy(() => import('./components/SearchDialog'));
1414
const FileRankDialog = React.lazy(() => import('./components/FileRankDialog'));
1515
const KeyboardShortcutsDialog = React.lazy(() => import('./components/KeyboardShortcutsDialog'));
16+
const SecurityFindingsDialog = React.lazy(() => import('./components/SecurityFindingsDialog'));
1617

1718
const SuspenseFallback = () => null;
1819

@@ -73,6 +74,7 @@ const App: React.FC = () => {
7374
selectedFileName={state.selectedFile?.path.split('/').pop()}
7475
isDark={state.isDark}
7576
processedData={state.processedData}
77+
onShowSecurityFindings={() => handlers.setIsSecurityFindingsOpen(true)}
7678
/>
7779
)}
7880

@@ -139,6 +141,26 @@ const App: React.FC = () => {
139141
onToggleIncludeDirectoryStructure={() => settings.setIncludeDirectoryStructure(!state.includeDirectoryStructure)}
140142
includeGitDiffs={state.includeGitDiffs}
141143
onToggleIncludeGitDiffs={() => settings.setIncludeGitDiffs(!state.includeGitDiffs)}
144+
exportFormat={state.exportFormat}
145+
onSetExportFormat={settings.setExportFormat}
146+
includePatterns={state.includePatterns}
147+
onSetIncludePatterns={settings.setIncludePatterns}
148+
ignorePatterns={state.ignorePatterns}
149+
onSetIgnorePatterns={settings.setIgnorePatterns}
150+
useDefaultPatterns={state.useDefaultPatterns}
151+
onToggleUseDefaultPatterns={() => settings.setUseDefaultPatterns(!state.useDefaultPatterns)}
152+
useGitignore={state.useGitignore}
153+
onToggleUseGitignore={() => settings.setUseGitignore(!state.useGitignore)}
154+
includeEmptyDirectories={state.includeEmptyDirectories}
155+
onToggleIncludeEmptyDirectories={() => settings.setIncludeEmptyDirectories(!state.includeEmptyDirectories)}
156+
showLineNumbers={state.showLineNumbers}
157+
onToggleShowLineNumbers={() => settings.setShowLineNumbers(!state.showLineNumbers)}
158+
removeEmptyLines={state.removeEmptyLines}
159+
onToggleRemoveEmptyLines={() => settings.setRemoveEmptyLines(!state.removeEmptyLines)}
160+
truncateBase64={state.truncateBase64}
161+
onToggleTruncateBase64={() => settings.setTruncateBase64(!state.truncateBase64)}
162+
exportSplitMaxChars={state.exportSplitMaxChars}
163+
onSetExportSplitMaxChars={settings.setExportSplitMaxChars}
142164
exportHeaderText={state.exportHeaderText}
143165
onSetExportHeaderText={settings.setExportHeaderText}
144166
exportInstructionText={state.exportInstructionText}
@@ -157,6 +179,17 @@ const App: React.FC = () => {
157179
</React.Suspense>
158180
)}
159181
</AnimatePresence>
182+
<AnimatePresence>
183+
{state.isSecurityFindingsOpen && (
184+
<React.Suspense fallback={<SuspenseFallback />}>
185+
<SecurityFindingsDialog
186+
isOpen={state.isSecurityFindingsOpen}
187+
onClose={() => handlers.setIsSecurityFindingsOpen(false)}
188+
findings={state.processedData?.securityFindings ?? []}
189+
/>
190+
</React.Suspense>
191+
)}
192+
</AnimatePresence>
160193
<AnimatePresence>
161194
{state.toastMessage && <Toast message={state.toastMessage} onDone={() => handlers.setToastMessage(null)} type={state.toastType} />}
162195
</AnimatePresence>

structure-insight/CHANGELOG.md

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,28 @@
11
# Changelog
22

3+
## [5.4.0] - 2026-04-12
4+
5+
### Features
6+
- 新增导出格式增强:仓库分析汇总、预计 Token 指标与敏感信息告警摘要
7+
- 新增浏览器端敏感内容扫描,支持在状态栏与导出结果中提示潜在密钥/私钥/内联凭据
8+
- 新增安全提示详情面板,可查看每条风险的文件位置、级别与命中片段
9+
- 新增导出拆分阈值,保存时可按字符数自动拆分为多份文件
10+
- 将导出中的 “Git Diffs” 明确更名为 “Edited Changes”,避免与真实 Git 工作区语义混淆
11+
- 扩展忽略规则支持,兼容分层 `.gitignore``.ignore`
12+
13+
### Platform
14+
- 注册 Service Worker,补齐 PWA 应用壳缓存与离线重访能力
15+
- 修复并统一 manifest/favicon 资源,移除失效的图标引用
16+
- 移除 `index.html` 中的外部 CDN 依赖,改为本地 Tailwind 构建、本地图标资源和本地语法高亮资源
17+
- 继续瘦身前端产物:将 FileTree / CodeView / StructureView 拆分为独立 chunk,主入口包体从约 599 kB 降至约 299 kB
18+
- 图标体系改为仅使用 solid 子集,并在构建阶段移除 `.ttf` 回退资源,仅保留 `woff2`
19+
- 新增 `typecheck``check` 脚本
20+
- 新增 GitHub Actions CI,覆盖安装、类型检查、测试与构建
21+
22+
### Documentation
23+
- 更新根 README 与应用 README,明确仓库结构、启动路径和可用脚本
24+
- 为本轮 P0/P1 工作补充设计文档与实施计划
25+
326
## [5.3.0] - 2025-03-30
427

528
### Bug Fixes

structure-insight/README.md

Lines changed: 44 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,55 @@
1-
<div align="center">
2-
<img width="1200" height="475" alt="GHBanner" src="https://github.com/user-attachments/assets/0aa67016-6eaf-458a-adb2-6e31a0763ed6" />
3-
</div>
1+
# Structure Insight App
42

5-
# Run and deploy Structure Insight
3+
Browser-first codebase analysis and export tooling for sharing repository context with AI systems.
64

7-
This contains everything you need to run your app locally.
5+
## What This App Does
86

9-
## Run Locally
7+
- Imports folders and `.zip` archives entirely in the browser
8+
- Builds a navigable tree view and code viewer
9+
- Lets you edit files in-app and export the current state
10+
- Supports layered `.gitignore` and `.ignore` filtering
11+
- Estimates token usage for loaded files
12+
- Flags likely sensitive content before you copy or save exports
13+
- Shows a dedicated security findings dialog for reviewing warning details
14+
- Can split large exports into multiple files during save
15+
- Registers as a PWA and caches the app shell for offline reuse after the first online load
16+
- Uses local build-time assets instead of runtime CDN dependencies for core UI styling, icons, and syntax highlighting
17+
- Splits heavier views like the file tree and code viewer into separate chunks to keep the initial app shell lighter
1018

11-
**Prerequisites:** Node.js
19+
## Development
1220

21+
Run all commands from this directory:
1322

14-
1. Install dependencies:
15-
`npm install`
16-
2. Run the app:
17-
`npm run dev`
23+
```bash
24+
npm install
25+
npm run dev
26+
```
1827

19-
## Deployment Troubleshooting
28+
Useful scripts:
2029

21-
### Error: "Cannot find cwd: .../structure-insight-web"
30+
```bash
31+
npm run typecheck
32+
npm test -- --run
33+
npm run build
34+
npm run check
35+
```
2236

23-
If you encounter an error like `Error: Cannot find cwd: /opt/buildhome/repo/structure-insight-web` during deployment (e.g., on Cloudflare Pages):
37+
## Repository Notes
2438

25-
This indicates the deployment service is expecting the project files to be in a subdirectory named `structure-insight-web`, but they are in the root of your repository.
39+
- The repository root contains the public project README.
40+
- CI runs from the repository root but uses this directory as the working directory.
41+
- Cloudflare Pages or similar platforms should point their root/build directory to `structure-insight/`.
2642

27-
**Fix:**
28-
1. Go to your deployment project settings (e.g., Cloudflare Pages > Settings > Build & deployments).
29-
2. Locate the **Root Directory** setting in "Build configurations".
30-
3. Change it to `/` (empty) to indicate the project is in the root directory.
43+
## Export Semantics
44+
45+
- `Edited Changes` represents differences between the imported file contents and your in-app edits.
46+
- It does **not** read the local git working tree or staged diff.
47+
- Token counts are estimates intended for planning and comparison, not exact model-token guarantees.
48+
49+
## Offline Notes
50+
51+
- The app shell no longer depends on external CDN resources in `index.html`.
52+
- Core styling is compiled locally with Tailwind.
53+
- Icons and syntax-highlighting resources are bundled or served from local project assets.
54+
- Font Awesome is reduced to the local solid subset with `woff2` output only.
55+
- First-load network access is still needed for the initial installation, but repeat visits can rely on cached local assets.

structure-insight/components/CodeView.tsx

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,11 @@
11

22
import React from 'react';
3+
import hljs from 'highlight.js/lib/common';
34
import { motion } from 'framer-motion';
45
import { FileContent, SearchOptions } from '../types';
56
import { marked } from 'marked';
67
import DOMPurify from 'dompurify';
78

8-
// hljs types provided by types/hljs.d.ts
9-
109
interface FileCardProps {
1110
file: FileContent;
1211
isEditing: boolean;
@@ -27,7 +26,7 @@ interface FileCardProps {
2726

2827
const IconButton: React.FC<{icon: string, title: string, onClick: () => void, disabled?: boolean, text?: string}> = ({icon, title, onClick, disabled, text}) => (
2928
<button onClick={onClick} className="flex items-center space-x-1.5 text-sm text-light-subtle-text dark:text-dark-subtle-text hover:text-light-text dark:hover:text-dark-text disabled:opacity-50 transition-colors" title={title} disabled={disabled}>
30-
<i className={`fa-regular ${icon}`}></i>
29+
<i className={`fa-solid ${icon}`}></i>
3130
{text && <span className="hidden sm:inline">{text}</span>}
3231
</button>
3332
);
@@ -172,10 +171,10 @@ const FileCard: React.FC<FileCardProps> = ({
172171
</div>
173172
<div className="flex justify-between items-center p-3 bg-light-header/80 dark:bg-dark-header/80 border-b border-light-border dark:border-dark-border sticky top-0 z-[1] backdrop-blur-sm">
174173
<div className="font-mono text-sm text-light-text dark:text-dark-text truncate flex items-center" title={file.path}>
175-
<i className="fa-regular fa-file-lines mr-2 text-light-subtle-text dark:text-dark-subtle-text"></i>
174+
<i className="fa-solid fa-file-lines mr-2 text-light-subtle-text dark:text-dark-subtle-text"></i>
176175
<span className={`truncate ${file.excluded ? 'line-through text-light-subtle-text dark:text-dark-subtle-text italic' : ''}`}>{file.path} {file.excluded && "(已排除)"}</span>
177176
<button onClick={() => onCopyPath(file.path)} className="ml-2 text-light-subtle-text hover:text-primary transition-colors flex items-center justify-center p-1 rounded hover:bg-light-border dark:hover:bg-dark-border/50" title="复制路径">
178-
<i className="fa-regular fa-copy text-xs"></i>
177+
<i className="fa-solid fa-copy text-xs"></i>
179178
</button>
180179
</div>
181180
<div className="flex items-center space-x-4 text-xs text-light-subtle-text dark:text-dark-subtle-text shrink-0 ml-2">
@@ -267,7 +266,7 @@ const CodeView: React.FC<CodeViewProps> = (props) => {
267266
if (!selectedFile) {
268267
return (
269268
<div className="flex flex-col items-center justify-center h-full text-center p-4 text-light-subtle-text dark:text-dark-subtle-text">
270-
<i className="fa-regular fa-file-code text-5xl mb-4"></i>
269+
<i className="fa-solid fa-file-code text-5xl mb-4"></i>
271270
<p className="font-semibold">选择一个文件</p>
272271
<p className="text-sm">从左侧资源管理器中选择一个文件以查看其内容。</p>
273272
</div>

0 commit comments

Comments
 (0)