moflo 4.8.77 → 4.8.79

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "moflo",
3
- "version": "4.8.77",
3
+ "version": "4.8.79",
4
4
  "description": "MoFlo — AI agent orchestration for Claude Code. Forked from ruflo/claude-flow with patches applied to source, plus feature-level orchestration.",
5
5
  "main": "dist/index.js",
6
6
  "type": "module",
@@ -112,7 +112,7 @@
112
112
  "@types/js-yaml": "^4.0.9",
113
113
  "@types/node": "^20.19.37",
114
114
  "eslint": "^8.0.0",
115
- "moflo": "^4.8.76",
115
+ "moflo": "^4.8.78",
116
116
  "tsx": "^4.21.0",
117
117
  "typescript": "^5.9.3",
118
118
  "vitest": "^4.0.0"
@@ -2,5 +2,5 @@
2
2
  * Auto-generated by build. Do not edit manually.
3
3
  * Source of truth: root package.json → scripts/sync-version.mjs
4
4
  */
5
- export const VERSION = '4.8.77';
5
+ export const VERSION = '4.8.79';
6
6
  //# sourceMappingURL=version.js.map
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@moflo/cli",
3
- "version": "4.8.77",
3
+ "version": "4.8.79",
4
4
  "type": "module",
5
5
  "main": "dist/src/index.js",
6
6
  "types": "dist/src/index.d.ts",
@@ -21,6 +21,7 @@
21
21
  *
22
22
  * @see https://github.com/eric-cielo/moflo/issues/412
23
23
  */
24
+ import { execFileSync } from 'node:child_process';
24
25
  import { homedir } from 'node:os';
25
26
  import { posix, isAbsolute, relative } from 'node:path';
26
27
  /** Container path where projectRoot is mounted. */
@@ -58,6 +59,42 @@ const TOOL_HOME_PATHS = [
58
59
  function needsToolHomeAccess(level) {
59
60
  return level === 'elevated' || level === 'autonomous';
60
61
  }
62
+ /**
63
+ * Cached GitHub token resolution. `null` means resolution was attempted
64
+ * and produced no token (gh missing or not authenticated); we cache the
65
+ * negative result too so we don't shell out on every step.
66
+ */
67
+ let cachedGhToken;
68
+ /**
69
+ * Resolve the GitHub auth token from the host's gh CLI.
70
+ *
71
+ * Synchronous because the docker-sandbox API is synchronous (callers
72
+ * build args in-line). Cached per-process — gh tokens don't change
73
+ * during a session. Failure is silent and returns null; the caller will
74
+ * still attempt the docker run (which may fail later if the step needs
75
+ * git auth) rather than blocking unrelated bash steps on gh availability.
76
+ */
77
+ export function resolveGhToken() {
78
+ if (cachedGhToken !== undefined)
79
+ return cachedGhToken;
80
+ try {
81
+ const out = execFileSync('gh', ['auth', 'token'], {
82
+ encoding: 'utf8',
83
+ stdio: ['ignore', 'pipe', 'ignore'],
84
+ timeout: 5000,
85
+ windowsHide: true,
86
+ }).trim();
87
+ cachedGhToken = out.length > 0 ? out : null;
88
+ }
89
+ catch {
90
+ cachedGhToken = null;
91
+ }
92
+ return cachedGhToken;
93
+ }
94
+ /** Reset the cached token. Test-only — production code should never call this. */
95
+ export function _resetGhTokenCacheForTesting() {
96
+ cachedGhToken = undefined;
97
+ }
61
98
  /**
62
99
  * Normalise a host path into the form Docker Desktop accepts on `-v` mounts.
63
100
  * Docker for Windows accepts either native Windows paths or the `/c/...`
@@ -173,6 +210,28 @@ export function buildDockerArgs(command, capabilities, projectRoot, options) {
173
210
  mountedContainerPaths.add(containerPath);
174
211
  }
175
212
  }
213
+ // Override git credential.helper to the gh CLI helper. The host's
214
+ // bind-mounted .gitconfig declares a helper that can't run in the
215
+ // Linux container (Windows: `manager` .exe; macOS: `osxkeychain`;
216
+ // Linux: libsecret/etc — all host-OS-specific). gh is installed in
217
+ // the sandbox image; with GH_TOKEN supplied via env (below), `gh
218
+ // auth git-credential` resolves credentials for HTTPS git ops.
219
+ // First entry (empty value) resets the inherited helper list; the
220
+ // second entry installs the gh helper as the only one. Applied via
221
+ // GIT_CONFIG_* env vars so no config file is modified.
222
+ args.push('-e', 'GIT_CONFIG_COUNT=2');
223
+ args.push('-e', 'GIT_CONFIG_KEY_0=credential.helper');
224
+ args.push('-e', 'GIT_CONFIG_VALUE_0=');
225
+ args.push('-e', 'GIT_CONFIG_KEY_1=credential.helper');
226
+ args.push('-e', 'GIT_CONFIG_VALUE_1=!gh auth git-credential');
227
+ // Inject GH_TOKEN so gh recognises the user as authenticated inside
228
+ // the container. Without this the credential.helper above runs but
229
+ // returns nothing — gh's host config file (`hosts.yml`) only stores
230
+ // the username when the token lives in the OS keyring, which is
231
+ // unreachable from a Linux container on Windows or macOS.
232
+ if (options.ghToken) {
233
+ args.push('-e', `GH_TOKEN=${options.ghToken}`);
234
+ }
176
235
  }
177
236
  // ── Network isolation ───────────────────────────────────────────────
178
237
  const hasNet = capabilities.some(c => c.type === 'net');
@@ -191,7 +250,13 @@ export function buildDockerArgs(command, capabilities, projectRoot, options) {
191
250
  * wrappers. `--rm` handles container cleanup, so `cleanup()` is a no-op.
192
251
  */
193
252
  export function wrapWithDocker(command, capabilities, projectRoot, options) {
194
- const args = buildDockerArgs(command, capabilities, projectRoot, options);
253
+ // For elevated/autonomous steps, auto-resolve the host gh token if the
254
+ // caller didn't supply one. Tests inject `ghToken` explicitly so the
255
+ // host's gh CLI never needs to run during unit tests.
256
+ const resolvedOptions = options.ghToken === undefined && needsToolHomeAccess(options.permissionLevel)
257
+ ? { ...options, ghToken: resolveGhToken() ?? undefined }
258
+ : options;
259
+ const args = buildDockerArgs(command, capabilities, projectRoot, resolvedOptions);
195
260
  return {
196
261
  bin: options.dockerBin ?? 'docker',
197
262
  args,