@@ -144,6 +144,8 @@ func RunPluginCommandWithRecord(ctx context.Context, envDir, pluginName, command
144144 }
145145 }
146146
147+ invokedCWD , _ := os .Getwd ()
148+
147149 // Build stdio request payload.
148150 req := map [string ]interface {}{
149151 "action" : command ,
@@ -153,6 +155,7 @@ func RunPluginCommandWithRecord(ctx context.Context, envDir, pluginName, command
153155 "bin" : filepath .Join (envDir , "bin" ),
154156 "workspace" : filepath .Join (envDir , "workspace" ),
155157 "plugin_dir" : pluginDir ,
158+ "cwd" : invokedCWD ,
156159 },
157160 "system" : map [string ]string {
158161 "os" : runtime .GOOS ,
@@ -489,17 +492,31 @@ func spawnStdio(ctx context.Context, spec *CommandSpec, pluginDir string, req ma
489492 }
490493
491494 // Resolve effective workdir.
495+ // NEW default: use user's invocation cwd (req.paths.cwd) so relative file paths behave naturally.
496+ // If spec.Workdir is set, it still wins (absolute or plugin-relative).
492497 resolvedWorkdir := absPluginDir
498+
499+ // 1) default to invocation cwd if provided
500+ if pm , ok := req ["paths" ].(map [string ]string ); ok {
501+ if c := strings .TrimSpace (pm ["cwd" ]); c != "" {
502+ resolvedWorkdir = c
503+ }
504+ }
505+
506+ // 2) explicit workdir in manifest overrides default
493507 if strings .TrimSpace (spec .Workdir ) != "" {
494508 if filepath .IsAbs (spec .Workdir ) {
495509 resolvedWorkdir = spec .Workdir
496510 } else {
497511 resolvedWorkdir = filepath .Join (absPluginDir , spec .Workdir )
498512 }
499513 } else {
500- scriptsDir := filepath .Join (absPluginDir , "scripts" )
501- if st , err := os .Stat (scriptsDir ); err == nil && st .IsDir () {
502- resolvedWorkdir = scriptsDir
514+ // 3) fallback for old behavior when cwd missing (best-effort)
515+ if resolvedWorkdir == absPluginDir {
516+ scriptsDir := filepath .Join (absPluginDir , "scripts" )
517+ if st , err := os .Stat (scriptsDir ); err == nil && st .IsDir () {
518+ resolvedWorkdir = scriptsDir
519+ }
503520 }
504521 }
505522
0 commit comments