Chapter 3: Installation and Configuration Baseline

April 13, 2026 ยท View on GitHub

Welcome to Chapter 3: Installation and Configuration Baseline. In this part of OpenCode AI Legacy Tutorial: Archived Terminal Agent Workflows and Migration to Crush, you will build an intuitive mental model first, then move into concrete implementation details and practical production tradeoffs.

This chapter covers reproducible legacy setup for controlled environments.

Learning Goals

  • install legacy binaries and scripts safely
  • configure environment and JSON settings deterministically
  • document exact versions for reproducibility
  • reduce setup drift across operators

Setup Guidance

  • pin known working release version
  • store config templates with environment assumptions
  • isolate legacy runtime from modern critical paths

Source References

Summary

You now have a reproducible setup baseline for legacy OpenCode operation.

Next: Chapter 4: Model Providers and Runtime Operations

Source Code Walkthrough

internal/lsp/methods.go

The Progress function in internal/lsp/methods.go handles a key part of this chapter's functionality:

}

// WorkDoneProgressCancel sends a window/workDoneProgress/cancel notification to the LSP server.
// The window/workDoneProgress/cancel notification is sent from  the client to the server to cancel a progress initiated on the server side.
func (c *Client) WorkDoneProgressCancel(ctx context.Context, params protocol.WorkDoneProgressCancelParams) error {
	return c.Notify(ctx, "window/workDoneProgress/cancel", params)
}

// DidCreateFiles sends a workspace/didCreateFiles notification to the LSP server.
// The did create files notification is sent from the client to the server when files were created from within the client. Since 3.16.0
func (c *Client) DidCreateFiles(ctx context.Context, params protocol.CreateFilesParams) error {
	return c.Notify(ctx, "workspace/didCreateFiles", params)
}

// DidRenameFiles sends a workspace/didRenameFiles notification to the LSP server.
// The did rename files notification is sent from the client to the server when files were renamed from within the client. Since 3.16.0
func (c *Client) DidRenameFiles(ctx context.Context, params protocol.RenameFilesParams) error {
	return c.Notify(ctx, "workspace/didRenameFiles", params)
}

// DidDeleteFiles sends a workspace/didDeleteFiles notification to the LSP server.
// The will delete files request is sent from the client to the server before files are actually deleted as long as the deletion is triggered from within the client. Since 3.16.0
func (c *Client) DidDeleteFiles(ctx context.Context, params protocol.DeleteFilesParams) error {
	return c.Notify(ctx, "workspace/didDeleteFiles", params)
}

// DidOpenNotebookDocument sends a notebookDocument/didOpen notification to the LSP server.
// A notification sent when a notebook opens. Since 3.17.0
func (c *Client) DidOpenNotebookDocument(ctx context.Context, params protocol.DidOpenNotebookDocumentParams) error {
	return c.Notify(ctx, "notebookDocument/didOpen", params)
}

This function is important because it defines how OpenCode AI Legacy Tutorial: Archived Terminal Agent Workflows and Migration to Crush implements the patterns covered in this chapter.

cmd/root.go

The attemptTUIRecovery function in cmd/root.go handles a key part of this chapter's functionality:

			defer tuiWg.Done()
			defer logging.RecoverPanic("TUI-message-handler", func() {
				attemptTUIRecovery(program)
			})

			for {
				select {
				case <-tuiCtx.Done():
					logging.Info("TUI message handler shutting down")
					return
				case msg, ok := <-ch:
					if !ok {
						logging.Info("TUI message channel closed")
						return
					}
					program.Send(msg)
				}
			}
		}()

		// Cleanup function for when the program exits
		cleanup := func() {
			// Shutdown the app
			app.Shutdown()

			// Cancel subscriptions first
			cancelSubs()

			// Then cancel TUI message handler
			tuiCancel()

			// Wait for TUI message handler to finish

This function is important because it defines how OpenCode AI Legacy Tutorial: Archived Terminal Agent Workflows and Migration to Crush implements the patterns covered in this chapter.

cmd/root.go

The initMCPTools function in cmd/root.go handles a key part of this chapter's functionality:


		// Initialize MCP tools early for both modes
		initMCPTools(ctx, app)

		// Non-interactive mode
		if prompt != "" {
			// Run non-interactive flow using the App method
			return app.RunNonInteractive(ctx, prompt, outputFormat, quiet)
		}

		// Interactive mode
		// Set up the TUI
		zone.NewGlobal()
		program := tea.NewProgram(
			tui.New(app),
			tea.WithAltScreen(),
		)

		// Setup the subscriptions, this will send services events to the TUI
		ch, cancelSubs := setupSubscriptions(app, ctx)

		// Create a context for the TUI message handler
		tuiCtx, tuiCancel := context.WithCancel(ctx)
		var tuiWg sync.WaitGroup
		tuiWg.Add(1)

		// Set up message handling for the TUI
		go func() {
			defer tuiWg.Done()
			defer logging.RecoverPanic("TUI-message-handler", func() {
				attemptTUIRecovery(program)
			})

This function is important because it defines how OpenCode AI Legacy Tutorial: Archived Terminal Agent Workflows and Migration to Crush implements the patterns covered in this chapter.

cmd/root.go

The setupSubscriptions function in cmd/root.go handles a key part of this chapter's functionality:


		// Setup the subscriptions, this will send services events to the TUI
		ch, cancelSubs := setupSubscriptions(app, ctx)

		// Create a context for the TUI message handler
		tuiCtx, tuiCancel := context.WithCancel(ctx)
		var tuiWg sync.WaitGroup
		tuiWg.Add(1)

		// Set up message handling for the TUI
		go func() {
			defer tuiWg.Done()
			defer logging.RecoverPanic("TUI-message-handler", func() {
				attemptTUIRecovery(program)
			})

			for {
				select {
				case <-tuiCtx.Done():
					logging.Info("TUI message handler shutting down")
					return
				case msg, ok := <-ch:
					if !ok {
						logging.Info("TUI message channel closed")
						return
					}
					program.Send(msg)
				}
			}
		}()

		// Cleanup function for when the program exits

This function is important because it defines how OpenCode AI Legacy Tutorial: Archived Terminal Agent Workflows and Migration to Crush implements the patterns covered in this chapter.

How These Components Connect

flowchart TD
    A[Progress]
    B[attemptTUIRecovery]
    C[initMCPTools]
    D[setupSubscriptions]
    E[Execute]
    A --> B
    B --> C
    C --> D
    D --> E