Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
89 commits
Select commit Hold shift + click to select a range
ad462f7
feat: inital repo browser commit
epmog Apr 30, 2026
dc9cb6b
feat: support bundle archives and add bundle upload/download commands
epmog Apr 30, 2026
d0ffb78
feat: add metadata tnd preview downloads to delay full bundle download
epmog Apr 30, 2026
7dc1d29
feat: make searching -> selecting feel good for local browsing
epmog Apr 30, 2026
007a3d5
feat: add bundle cache commands, bundle list, job history as a locati…
epmog May 1, 2026
1d989de
feat: add share button, parameter values in preview
epmog May 1, 2026
b039012
feat: resolve parameters in job names
epmog May 1, 2026
bb307aa
feat: add archive safety, s3 error handling, and double click to sele…
epmog May 1, 2026
abf9e6a
fix: only support .ojd (.zip) format
epmog May 29, 2026
ba42e80
feat: add translations for new labels
epmog May 29, 2026
c4882ab
chore: update design doc
epmog May 29, 2026
035795a
chore: swap from 's3 job bundles', to 'queue job bundles'
epmog Jun 11, 2026
4a1d960
fix: use config creds for queue bundles
epmog Jun 11, 2026
402d9f5
chore: move source selection to top of browser
epmog Jun 11, 2026
5a28736
feat: add 'show hidden folders' option
epmog Jun 11, 2026
758b25c
feat: Show bundle parameter preview as table
epmog Jun 11, 2026
0214c20
fix: warning label when queue bundles are not available
epmog Jun 12, 2026
c740476
fix: upload .ojd not .zip
epmog Jun 12, 2026
4b324b0
fix: bundle download now respects output path
epmog Jun 12, 2026
d84d027
fix: handle s3 user metadata limit
epmog Jun 12, 2026
ad37bb1
fix: add confirmation for overwriting existing bundle on queue
epmog Jun 12, 2026
048e9e0
fix: prevent directory traversal with symlinks
epmog Jun 12, 2026
1460698
chore: update doc and s3 repo apis
epmog Jun 12, 2026
e484980
fix: sanitize bundle downloads
epmog Jun 12, 2026
2a2d1b1
fix: remove access to private _local_repo variable in browser
epmog Jun 12, 2026
1438003
fix: normalize etag comparison
epmog Jun 12, 2026
42b9ecf
chore: update docs
epmog Jun 12, 2026
a3b1b48
feat: merge share and export button
epmog Jun 13, 2026
e129b11
feat: implement show/hide functionality for queue bundles
epmog Jun 15, 2026
602b1d1
fix: use queue user boto3 session for bundle browsing
epmog Jun 15, 2026
4841239
fix: download/upload to use queue role
epmog Jun 15, 2026
0fa2c7c
feat: add deadline bundle info command
epmog Jun 15, 2026
a0f8743
fix: show .ojd in Local source, and only use s3 metadata if bundle no…
epmog Jun 16, 2026
7e3017e
feat(ui): theme-aware, WCAG-AA contrast warning banner
phil-IO-p Jun 16, 2026
2cb11ba
feat(ui): polish job bundle browser preview panel, tree, and layout
phil-IO-p Jun 16, 2026
ba4b24d
fix: can't determine (required) from only metadata
epmog Jun 16, 2026
5080431
fix: dynamically allocate metadata limit
epmog Jun 16, 2026
2560484
feat: expansdble parameterrs/steps in preview panel
epmog Jun 16, 2026
8e22c75
feat: change export bundle to save bundle as
epmog Jun 16, 2026
84f06fb
fix: let user know that no bundle were found
epmog Jun 16, 2026
4dadbd1
fix: translate save as dialog
epmog Jun 16, 2026
0f8070a
feat: remember bundle selection per source
epmog Jun 16, 2026
0a9f931
fix: reject control characters in bundle upload
epmog Jun 17, 2026
22fb173
fix: modify job bundle directory actually takes effect
epmog Jun 17, 2026
7de931d
feat: upload .ojd files directly
epmog Jun 17, 2026
0aca56e
feat: re-use already extracted local bundles based on mtime
epmog Jun 17, 2026
80ec978
feat: add progress bar for archive/upload
epmog Jun 18, 2026
15f4a31
chore: remove env variable for bundle repo
epmog Jun 18, 2026
8f598b3
fix: upload/download CLI now report progress
epmog Jun 18, 2026
24fa862
fix: isolate bundle tests from user's cache
epmog Jun 18, 2026
55b3165
fix: have cancelled loads reshow browser
epmog Jun 18, 2026
b9373c1
feat: speed up browser loading
epmog Jun 19, 2026
7ffe93d
feat: add tab navigation to browser windows
epmog Jun 19, 2026
bbab02a
feat: add tab navigation to save dialog
epmog Jun 19, 2026
8687d99
test: fix test after rebase
epmog Jun 19, 2026
7addbae
test: add missing tests
epmog Jun 19, 2026
fd7971a
fix: use existing commands for mcp
epmog Jun 19, 2026
6d5cc51
fix: UTF-8 for metadata calculations and misc. bugs
epmog Jun 19, 2026
a0b837f
feat: make repo functionality public
epmog Jun 22, 2026
1ac0684
chore: de-dupe metadata code, ensure bundle is updated when saving
epmog Jun 22, 2026
1b0e548
chore: fix TypeError
epmog Jun 22, 2026
78b51c3
fix: remove traversal from names, validate metadata ints, normalize s…
epmog Jun 22, 2026
a3c3070
feat: add json output to bundle download
epmog Jun 22, 2026
05490e2
chore: fix 3.9 linting
epmog Jun 22, 2026
060faba
chore: rename finished signal to done to avoid shadowing
epmog Jul 8, 2026
688d892
fix: uploading bundle always showed 1KB size
epmog Jul 8, 2026
6b88e65
fix: failed bundle generation uploaded original bundle
epmog Jul 8, 2026
1421084
chore: removed unused function
epmog Jul 8, 2026
5f9c4a1
fix: support non-ascii characters in s3 metadata
epmog Jul 8, 2026
0c449d2
fix: sanitzie --name override for job bundle upload
epmog Jul 8, 2026
58a502f
fix: move S3 head_object off the Qt main thread
epmog Jul 8, 2026
b2fcf38
fix(ui): use palette text color when unhiding a bundle
epmog Jul 8, 2026
98ebb39
fix(ui): cancel bundle downloads cooperatively, not via terminate
epmog Jul 8, 2026
8f48d14
fix: cap preview data for job bundles in browser
epmog Jul 9, 2026
d380985
fix: apply limits to downloads/extraction, and spool downloadings
epmog Jul 10, 2026
5c68c1a
fix: reject non-zip archive .ojd files
epmog Jul 10, 2026
5e9248f
fix: .ojd are uploaded with 'application/zip' ContentType
epmog Jul 10, 2026
e5ca948
fix: all preview is Qt.PlainText
epmog Jul 10, 2026
6738b60
feat: add inspect bundle button to preview
epmog Jul 10, 2026
730e6b2
fix: banner shown when you can't acecss queue and no bundles found if…
epmog Jul 13, 2026
19adb94
feat: add bundle size to download button
epmog Jul 13, 2026
d49529c
fix: local/history are open bundle
epmog Jul 13, 2026
702340e
chore: change spacing/size/ordering of preview contents
epmog Jul 13, 2026
f66dcaf
chore: make path look non-editable
epmog Jul 13, 2026
9b13cd4
fix: collapse all unless selected when clearing filter
epmog Jul 13, 2026
6afabe4
feat: preload 1 level of bundles to help with filtering
epmog Jul 14, 2026
1f19cdd
feat: swap from .bundle_visbility to concurrent S3 HEAD
epmog Jul 14, 2026
559eee1
feat: show/hide is now a local
epmog Jul 14, 2026
04a9507
chore: remove bundle cache clean/update commands
epmog Jul 15, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
635 changes: 635 additions & 0 deletions docs/design/job-bundle-browser.md

Large diffs are not rendered by default.

15 changes: 14 additions & 1 deletion src/deadline/_mcp/registry.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
from typing import Any, Callable, List, Optional, TypedDict, Dict

from ..client import api
from .tools import job, logs
from .tools import job, logs, bundles


class ToolDefinition(TypedDict):
Expand Down Expand Up @@ -115,4 +115,17 @@ def get_all_tool_names() -> List[str]:
"item_offset",
],
},
# Bundle sharing tools
"list_shared_bundles": {
"func": bundles.list_shared_bundles,
"param_names": ["farm_id", "queue_id", "show_hidden"],
},
"upload_bundle": {
"func": bundles.upload_bundle,
"param_names": ["job_bundle", "name", "farm_id", "queue_id"],
},
"download_bundle": {
"func": bundles.download_bundle,
"param_names": ["bundle_name", "output_dir", "farm_id", "queue_id"],
},
}
100 changes: 100 additions & 0 deletions src/deadline/_mcp/tools/bundles.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.

"""
Deadline Cloud Bundle sharing tools for MCP.
"""

import json
from typing import Any, Dict, Optional

from click.testing import CliRunner

from ...client.cli import main


def list_shared_bundles(
farm_id: Optional[str] = None,
queue_id: Optional[str] = None,
show_hidden: bool = False,
) -> Dict[str, Any]:
"""List job bundles shared on the queue.

Returns a list of bundles with their name and format.
Hidden bundles are excluded by default unless show_hidden is True.
"""
args = ["bundle", "list", "--queue", "--output", "json"]
if farm_id:
args.extend(["--farm-id", farm_id])
if queue_id:
args.extend(["--queue-id", queue_id])
if show_hidden:
args.append("--show-hidden")

runner = CliRunner()
result = runner.invoke(main, args)

if result.exit_code != 0:
return {"success": False, "error": result.output.strip()}
return {"bundles": json.loads(result.output)}


def upload_bundle(
job_bundle: str,
name: Optional[str] = None,
farm_id: Optional[str] = None,
queue_id: Optional[str] = None,
) -> Dict[str, Any]:
"""Upload a local job bundle to the queue as a shared .ojd archive.

Args:
job_bundle: Path to a job bundle directory or .ojd archive file.
name: Override the bundle name (defaults to directory/file name).
farm_id: The farm ID (uses default if not specified).
queue_id: The queue ID (uses default if not specified).
"""
args = ["bundle", "upload", job_bundle]
if name:
args.extend(["--name", name])
if farm_id:
args.extend(["--farm-id", farm_id])
if queue_id:
args.extend(["--queue-id", queue_id])

runner = CliRunner()
result = runner.invoke(main, args, input="y\n")

if result.exit_code != 0:
return {"success": False, "error": result.output.strip()}
return {"success": True, "message": result.output.strip()}


def download_bundle(
bundle_name: str,
output_dir: Optional[str] = None,
farm_id: Optional[str] = None,
queue_id: Optional[str] = None,
) -> Dict[str, Any]:
"""Download a shared bundle from the queue to a local directory.

Args:
bundle_name: Name of the bundle to download.
output_dir: Local directory to download to (uses cache if not specified).
farm_id: The farm ID (uses default if not specified).
queue_id: The queue ID (uses default if not specified).
"""
args = ["bundle", "download", bundle_name, "--output", "json"]
if output_dir:
args.extend(["-o", output_dir])
if farm_id:
args.extend(["--farm-id", farm_id])
if queue_id:
args.extend(["--queue-id", queue_id])

runner = CliRunner()
result = runner.invoke(main, args)

if result.exit_code != 0:
return {"success": False, "error": result.output.strip()}

data = json.loads(result.output)
return {"success": True, "path": data["path"]}
Loading