Why can't buf generate find a file in my import statements?

Usually, this issue is because of a mismatch between the relative locations of the input to the buf generate command and the location specified in the import path. The buf generate command uses the location of your module's buf.yaml file as the root by default, so with this directory structure:

├── buf.gen.yaml
├── buf.yaml
├── proto
│   └── foo
│       └── foo.proto
│   └── bar
│       └── bar.proto

if you run buf generate from the root, then your import paths should be an absolute path from that location. For example, if you wanted bar.proto to import foo.proto, the statement should be:

import "proto/foo/foo.proto";

However, if you specify an input to buf generate other than the module's root, the input will be prepended to the import path when looking for the file. For example, if you pass the proto directory as the input:

$ buf generate proto

then the Buf CLI looks for foo.proto at proto/proto/foo/foo.proto, which doesn't exist. You would need to change your import path to be:

import "foo/foo.proto";

My imports are working, but now I get "unknown type" errors when trying to use my imported type.

When importing from another package, you need to reference your types using the full package name. So, using the above directory structure, importing a Foo into our bar.proto file, would look like this:

syntax = "proto3";

package proto.bar;

import "proto/foo/foo.proto";

message Bar {
  proto.foo.Foo myFoo = 1;  // Note the full package name

Is there an SDK to run Buf CLI commands in Go (or any other language)?

No, we don't have an SDK for the Buf CLI. If you want to use the Buf CLI as part of some automation, then you should shell out to it.

How do I check whether generated code is up-to-date?

Run buf generate and check for a diff in your VCS (either locally or as part of your CI workflow).