moflo 4.8.78 → 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.78",
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.77",
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.78';
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.78",
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/...`
@@ -177,8 +214,8 @@ export function buildDockerArgs(command, capabilities, projectRoot, options) {
177
214
  // bind-mounted .gitconfig declares a helper that can't run in the
178
215
  // Linux container (Windows: `manager` .exe; macOS: `osxkeychain`;
179
216
  // Linux: libsecret/etc — all host-OS-specific). gh is installed in
180
- // the sandbox image and `.config/gh` is bind-mounted, so
181
- // `gh auth git-credential` supplies the token for HTTPS git ops.
217
+ // the sandbox image; with GH_TOKEN supplied via env (below), `gh
218
+ // auth git-credential` resolves credentials for HTTPS git ops.
182
219
  // First entry (empty value) resets the inherited helper list; the
183
220
  // second entry installs the gh helper as the only one. Applied via
184
221
  // GIT_CONFIG_* env vars so no config file is modified.
@@ -187,6 +224,14 @@ export function buildDockerArgs(command, capabilities, projectRoot, options) {
187
224
  args.push('-e', 'GIT_CONFIG_VALUE_0=');
188
225
  args.push('-e', 'GIT_CONFIG_KEY_1=credential.helper');
189
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
+ }
190
235
  }
191
236
  // ── Network isolation ───────────────────────────────────────────────
192
237
  const hasNet = capabilities.some(c => c.type === 'net');
@@ -205,7 +250,13 @@ export function buildDockerArgs(command, capabilities, projectRoot, options) {
205
250
  * wrappers. `--rm` handles container cleanup, so `cleanup()` is a no-op.
206
251
  */
207
252
  export function wrapWithDocker(command, capabilities, projectRoot, options) {
208
- 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);
209
260
  return {
210
261
  bin: options.dockerBin ?? 'docker',
211
262
  args,