> ## Documentation Index
> Fetch the complete documentation index at: https://dev.marginnote.com.cn/llms.txt
> Use this file to discover all available pages before exploring further.

# 列出任务包

> 列出现存的拆书任务包，包含运行中的作业，以及 App 重启后留在磁盘上的目录。各条目的字段含义见 `BundleEntry`。

条目的时间基准随类别不同。磁盘上的包按目录创建时间计，作业条目按作业
开始时间计。因此运行中的长作业不会因为开始时间早于 `since` 而从增量轮询里消失，
该条目的时间戳也不会随进度前进。

缺少的可选字段视为该字段不存在，不得视为空值。

`jobId` 说明不了作业所属的会话。经 prepare 登记的包都有该字段，App 重启后由磁盘标记
回带的包也有，判断作业是否属于本轮要看 `state`。

响应里不含标题、预设与来源。




## OpenAPI

````yaml /openapi/plugin-api.yaml get /bundles
openapi: 3.1.0
info:
  title: 场景插件 API
  summary: 场景插件在网页面板里可以调用的接口。
  description: >
    场景插件的面板是一个网页。页面里向 `/bridge/v1` 发请求，就能读写 MarginNote 里的数据。

    请求由 MarginNote 处理，与外部命令行工具共用同一套处理代码。外部工具要带令牌，面板不必带。

    面板页面从 `mnpanel://panel/index.html` 加载，因此 `fetch('/bridge/v1' + path)`
    属于同源请求。


    面板调用受这些条件约束：


    - 请求不带令牌，本文件也不声明安全方案。

    - 页面能调用哪些接口，取决于两份名单。模板里的 `plugins` 名单和沉浸态决定面板能不能建好，
      网页面板白名单决定页面能调哪些接口。不在白名单里的请求返回 `403`，
      错误码为 `IN_PROCESS_NOT_ALLOWED`。
    - `GET /capabilities` 里的 `requiresMax` 只约束外部 Agent。面板的请求在 MarginNote 进程内处理，
      不受令牌、订阅状态与跨设备批准的限制，能否调用只看该路径是否在白名单内。
    - 写操作里的 `addon`，MarginNote 会改写为当前面板所属插件的 id；`confirm` 由 MarginNote 补上。
      页面填的值不会生效。

    用 `mn.api(path, opts)` 读取数据。该方法始终将 Response Body 按 JSON 解析，相当于

    `fetch('/bridge/v1' + path, opts).then(r => r.json())`。


    响应的内容不是 JSON 的接口，改用 `fetch`：


    - `GET /guide` 返回 Markdown 正文。

    - `GET /notes/{noteid}/render` 返回卡片长图或 PDF。

    - `GET /documents/{bookmd5}/pages/{index}/content/{contentId}` 返回图片。

    - `GET /bundles/{bundleId}/files` 带 `?path=` 时返回该文件的原始字节。


    调用失败时 Promise 不会进入 reject。MarginNote 把错误对象

    `{"error":{"code":"…","message":"…"}}` 当作 Response Body 返回，因此结果落在 resolve 里。

    判断调用结果看响应里是否带 `error`，写操作另看响应里的 `persisted`。


    接口清单、各项上限与 Request Body 结构随 MarginNote 的版本变化，运行时以 `GET /capabilities` 与

    `GET /guide` 返回的内容为准。
  version: '0.91'
servers: []
security: []
tags:
  - name: 能力与状态
    description: 读取 MarginNote 的能力、版本与当前上下文。调用其他接口之前先读这组。
  - name: 卡片与摘录
    description: 卡片的读取与写入、摘录的创建、批注、标签、元数据与留白。
  - name: 手写会话
    description: 手写层、作答纸、练习准备清单与会话记录的读取与提交。
  - name: 学习集与卡组
    description: 学习集结构、脑图树、子脑图、色板、快照与复习卡组。
  - name: 文档与页面
    description: 文档目录、页文本、页内注释面、摘录清单与同步诊断。
  - name: 导出与 Anki
    description: 文档导出计划、导出文件、Anki 导出能力、作业与产物。
  - name: 查找
    description: 跨库搜索、文件夹列表与学习集列表。
  - name: 界面与模板
    description: 读取当前界面状态与沉浸模板。
  - name: 插件辅助
    description: 面板辅助脚本、已配对设备与本机 helper 信息。
  - name: 任务包与同步诊断
    description: 拆书任务包与旧 CloudKit 同步诊断。
paths:
  /bundles:
    get:
      tags:
        - 任务包与同步诊断
      summary: 列出任务包
      description: |
        列出现存的拆书任务包，包含运行中的作业，以及 App 重启后留在磁盘上的目录。各条目的字段含义见 `BundleEntry`。

        条目的时间基准随类别不同。磁盘上的包按目录创建时间计，作业条目按作业
        开始时间计。因此运行中的长作业不会因为开始时间早于 `since` 而从增量轮询里消失，
        该条目的时间戳也不会随进度前进。

        缺少的可选字段视为该字段不存在，不得视为空值。

        `jobId` 说明不了作业所属的会话。经 prepare 登记的包都有该字段，App 重启后由磁盘标记
        回带的包也有，判断作业是否属于本轮要看 `state`。

        响应里不含标题、预设与来源。
      operationId: getBundles
      parameters:
        - $ref: '#/components/parameters/Origin'
        - $ref: '#/components/parameters/Since'
      responses:
        '200':
          description: 任务包与作业条目。条目可能还有未列出的字段，外层结构的键名未取到。
          content:
            application/json:
              schema:
                type: object
                properties:
                  items:
                    type: array
                    items: {}
                    description: 实测为空数组，条目结构没有依据。
                  bridgeApiVersion:
                    type: string
                  bundles:
                    type: array
                    items:
                      $ref: '#/components/schemas/BundleEntry'
                    description: ⚠️
                description: 外层键名未取到，条目结构见 `BundleEntry`。
              examples:
                assembled:
                  summary: 一条运行中的作业与一条已导入的包，构造示例
                  value:
                    bundles:
                      - bundleId: 6F1C0A44-7E3B-4A21-9A55-0B2D8C1E99A1
                        jobId: 41D2E9C7-3A80-4F16-8B44-7C5E1A0D2F63
                        bundlePath: /Users/mnuser/Documents/MindBooksBreakdown/6F1C0A44
                        topicid: 77012CA0-48E8-4D29-B5F5-1EEA927AE086
                        bookmd5: >-
                          8daef026f17a04db9b325c86366419936de1ef8b454218998990a3cef6f467a7
                        createdAt: '2026-10-06T21:40:12Z'
                        state: preparing
                        progress:
                          pagesDone: 37
                          pagesTotal: 128
                        running: true
                      - bundleId: 2B7E5D91-0C48-4E77-A1F3-6D90B2C4E518
                        jobId: 8C1A4F20-5E96-4B37-9D82-1A6F3E0C7B45
                        bundlePath: /Users/mnuser/Documents/MindBooksBreakdown/2B7E5D91
                        topicid: 77012CA0-48E8-4D29-B5F5-1EEA927AE086
                        bookmd5: >-
                          8daef026f17a04db9b325c86366419936de1ef8b454218998990a3cef6f467a7
                        createdAt: '2026-09-30T09:12:44Z'
                        state: imported
                        version: 2
                        rootNoteId: B9F3696A-AF8A-43B2-A8A2-2791717F1695
                measured:
                  summary: 实测于 2026-10-07，App 0.91
                  value:
                    items: []
                    bridgeApiVersion: '0.91'
      x-codeSamples:
        - lang: javascript
          label: 列出自己建立的任务包，找出运行中的包
          source: |
            const r = await mn.api('/bundles?origin=bridge');
            const jobs = (r.bundles || []).filter(b => b.state === 'preparing');
            mn.log(jobs.length, jobs[0] && jobs[0].progress);
components:
  parameters:
    Origin:
      name: origin
      in: query
      required: false
      description: 只看经接口创建的任务包。
      schema:
        type: string
        enum:
          - bridge
    Since:
      name: since
      in: query
      required: false
      description: 按时间过滤。磁盘上的任务包按目录创建时间计，作业条目按作业开始时间计。
      schema:
        type: string
  schemas:
    BundleEntry:
      type: object
      properties:
        bundleId:
          type: string
        jobId:
          type: string
        bundlePath:
          type: string
          description: 包在磁盘上的位置。
        topicid:
          type: string
        bookmd5:
          type: string
        createdAt:
          type: string
        state:
          type: string
          description: >-
            包的状态。`preparing` 表示作业运行中，同时返回 `progress`； `prepared` 与 `imported`
            表示包可用，同时返回 `version` 与 `rootNoteId`； `failed` 表示作业失败，或 App
            中途重启后遗留的残留，同时返回 `error`，须调用删除任务包接口清理； `cancelled` 表示包已取消。仅
            `prepared` 与 `imported` 视为可用，其余各档一律视为不可用。
          enum:
            - preparing
            - prepared
            - imported
            - failed
            - cancelled
        version:
          type: number
          description: 已导入的次数，0 表示还没导入。只在已准备与已导入的条目上出现。
        rootNoteId:
          type: string
          description: 导入后生成的根卡。只在已准备与已导入的条目上出现。
        progress:
          type: object
          description: 只在正在准备的条目上出现。
          properties:
            pagesDone:
              type: number
            pagesTotal:
              type: number
        running:
          type: boolean
          description: 只在作业条目上出现。
        error:
          type: string
          description: 失败条目上的原因。

````

This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.