Skip to content

feat: Deploy template selection, PTY terminal and assistant transcript fixes#68

Merged
nfebe merged 6 commits into
mainfrom
feat/issue-138-improvements
Jun 8, 2026
Merged

feat: Deploy template selection, PTY terminal and assistant transcript fixes#68
nfebe merged 6 commits into
mainfrom
feat/issue-138-improvements

Conversation

@nfebe

@nfebe nfebe commented Jun 8, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Image and compose deploys can optionally select an app template. Image mode prefills the container port and mounts and keeps the user's image; both modes send the selection so the agent prepares directories, environment files and ownership. Required mounts are preselected but stay editable, and the full selection is sent so deselections stick.
  • The file manager's Hidden toggle starts from the persisted agent setting (default: shown) and is configurable in Settings.
  • The system terminal speaks the raw PTY stream protocol, reusing the container terminal component: interactive and full-screen programs work, resizes propagate, blocked commands are cancelled with a notice.
  • Seeded assistant prompts are flagged so only messages the user types appear in the chat.
  • Version 0.3.0.

Companion agent changes: flatrun/agent#142

nfebe added 5 commits June 8, 2026 01:40
The file manager's Hidden toggle now starts from a setting persisted on
the agent instead of always starting off. Hidden files are shown by
default and the preference can be changed from the Settings page.
Image and compose deployments can now select an app template. For image
deploys the selection prefills the container port and bind mounts while
the generated compose keeps the user's image. For both modes the
selection is sent with the deployment so the agent prepares
directories, environment files and ownership. Compose content written
by the user stays untouched.

Required mounts are preselected but stay editable in every mode, and
the full selection is sent so deselecting a required mount sticks.
Prompts composed by the product when opening the assistant are flagged
so the agent excludes them from the visible conversation. Only messages
the user types appear in the chat.
The system terminal now speaks the same raw stream protocol as the
container terminal, attached to a real PTY on the host. Interactive and
terminal-control programs work, keystrokes reach the running program
directly, and resizes propagate. Blocked commands are cancelled with a
notice instead of returning a synthetic error.
@sourceant

sourceant Bot commented Jun 8, 2026

Copy link
Copy Markdown

Code Review Summary

The PR introduces version 0.3.0, featuring PTY terminal support, app template selection during deployment, and improvements to the file manager's hidden file handling. It also refines how assistant transcripts handle seeded messages.

🚀 Key Improvements

  • Modularization of terminal logic by making ContainerTerminal.vue reusable via wsPath prop.
  • Support for selecting app templates in custom Compose and Image deployment modes.
  • Persisted settings for hidden files in the File Manager.
  • Seeded assistant messages are now correctly flagged to remain hidden from the UI transcript.

💡 Minor Suggestions

  • Ensure consistent port fallbacks when switching templates.
  • Sanitize URL path concatenation in terminal logic.

@sourceant sourceant Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review complete. See the overview comment for a summary.

const showHiddenFiles = ref(true);
const hideSystemFolders = ref(true);

const loadShowHiddenSetting = async () => {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The default value of showHiddenFiles is set to true (line 579) but then potentially overwritten by an async call. If the API call is slow, the UI might flicker from showing to hiding hidden files. Consider a loading state or a more robust sync mechanism if this is critical.

Suggested change
const loadShowHiddenSetting = async () => {
const loadShowHiddenSetting = async () => {
try {
const response = await configApi.get("files.show_hidden");
const value = response.data.entry?.value;
if (typeof value === "boolean") {
showHiddenFiles.value = value;
}
} catch (err) {
console.debug("Could not load hidden files setting, using default", err);
}
};

@@ -1044,7 +1082,6 @@
<input
type="checkbox"
:checked="getMountSelection(mount.id)?.enabled"

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The :disabled="mount.required" attribute was removed. While the PR description mentions that required mounts stay editable, ensure the backend/agent can handle a user deselecting a mount that the template identifies as 'required'.

Suggested change
:checked="getMountSelection(mount.id)?.enabled"
:checked="getMountSelection(mount.id)?.enabled"
@change="toggleMount(mount.id)"

@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Jun 8, 2026

Copy link
Copy Markdown

Deploying flatrun-ui with  Cloudflare Pages  Cloudflare Pages

Latest commit: b826deb
Status: ✅  Deploy successful!
Preview URL: https://e9efbf8a.flatrun-ui.pages.dev
Branch Preview URL: https://feat-issue-138-improvements.flatrun-ui.pages.dev

View logs

@sourceant sourceant Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review complete. See the overview comment for a summary.

if (apiUrl.startsWith("http")) {
const url = new URL(apiUrl);
return `${protocol}//${url.host}/api/containers/${props.containerId}/exec`;
return `${protocol}//${url.host}${path}`;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The URL host and path concatenation should ensure that the path starts with a single slash to avoid malformed URLs if path or url.host formatting varies.

Suggested change
return `${protocol}//${url.host}${path}`;
return `${protocol}//${url.host}${path.startsWith('/') ? '' : '/'}${path}`;


const onTemplatePresetChange = () => {
const app = templatePresetApp.value;
if (!app) {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When switching the template to 'None' (app is null), existing networking ports previously set by a template are not cleared. This might lead to unexpected port configurations if the user switches templates multiple times.

Suggested change
if (!app) {
if (!app) {
form.mounts = [];
form.networking.ports = [{ containerPort: 80, hostPort: "", expose: true }];
return;
}

generatingCompose.value = true;
try {
const enabledMounts = form.mounts.filter((m) => m.enabled);
const firstPort = form.networking.ports[0] || { containerPort: 80, hostPort: "" };

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When generating compose from an image with a template, the container port is hardcoded to 80 if no port is defined. It would be more consistent to use app.container_port as the fallback if available.

Suggested change
const firstPort = form.networking.ports[0] || { containerPort: 80, hostPort: "" };
const fallbackPort = templatePresetApp.value?.container_port || 80;
const firstPort = form.networking.ports[0] || { containerPort: fallbackPort, host_port: "" };

@nfebe nfebe merged commit 4aa7a5f into main Jun 8, 2026
5 checks passed
@nfebe nfebe deleted the feat/issue-138-improvements branch June 8, 2026 01:15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant