@galda/cli 0.10.106 → 0.10.107
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/engine/lib.mjs +38 -0
- package/engine/server.mjs +10 -2
- package/package.json +1 -1
package/engine/lib.mjs
CHANGED
|
@@ -3609,6 +3609,44 @@ export function pickChromePath(env = {}, exists = () => false) {
|
|
|
3609
3609
|
return chromeCandidates(env).find((c) => exists(c)) ?? null;
|
|
3610
3610
|
}
|
|
3611
3611
|
|
|
3612
|
+
// What THIS machine can and cannot do, stated before the person spends an hour
|
|
3613
|
+
// reading the absence as a product bug. Two capabilities are host-dependent and
|
|
3614
|
+
// silently degrade today: without Chrome nothing can take a screenshot or verify
|
|
3615
|
+
// in a browser, and without a native picker "Open folder…" cannot open Finder.
|
|
3616
|
+
//
|
|
3617
|
+
// Every check here is ADVISORY. None of them stop anything — the app works with
|
|
3618
|
+
// neither. That is deliberately NOT testEnvironmentPreflight's blocking/canRun
|
|
3619
|
+
// model (which answers "can `npm test` even start"): mixing the two is what made
|
|
3620
|
+
// a missing puppeteer read as a failed verification.
|
|
3621
|
+
// (`existsFn`/`env` are injected so this stays a pure function under test.)
|
|
3622
|
+
export function hostReadiness({ platform = 'darwin', env = {}, existsFn = () => false } = {}) {
|
|
3623
|
+
const chrome = pickChromePath(env, existsFn);
|
|
3624
|
+
const onPath = (cmd) => isCommandOnPath(cmd, {
|
|
3625
|
+
pathEnv: env.PATH ?? '', sep: platform === 'win32' ? ';' : ':', pathExt: env.PATHEXT ?? '', existsFn,
|
|
3626
|
+
});
|
|
3627
|
+
// macOS and Windows ship theirs; Linux has two common ones and neither is a given.
|
|
3628
|
+
const picker = platform === 'darwin' ? 'osascript'
|
|
3629
|
+
: platform === 'win32' ? 'powershell.exe'
|
|
3630
|
+
: (onPath('zenity') ? 'zenity' : 'kdialog');
|
|
3631
|
+
const hasPicker = onPath(picker);
|
|
3632
|
+
return [
|
|
3633
|
+
{
|
|
3634
|
+
id: 'chrome',
|
|
3635
|
+
ok: Boolean(chrome),
|
|
3636
|
+
detail: chrome
|
|
3637
|
+
? `Chrome/Chromium: ${chrome}`
|
|
3638
|
+
: 'No Chrome/Chromium found — screenshots and browser checks are unavailable',
|
|
3639
|
+
},
|
|
3640
|
+
{
|
|
3641
|
+
id: 'folder-picker',
|
|
3642
|
+
ok: hasPicker,
|
|
3643
|
+
detail: hasPicker
|
|
3644
|
+
? `Native folder picker: ${picker}`
|
|
3645
|
+
: `No native folder picker (${picker} is not installed) — Open folder… asks you to type the path`,
|
|
3646
|
+
},
|
|
3647
|
+
];
|
|
3648
|
+
}
|
|
3649
|
+
|
|
3612
3650
|
// `node <manager>/engine/shot.mjs <url|file> <out.png> [--width N] [--height N]
|
|
3613
3651
|
// [--full] [--wait MS] [--wait-for SELECTOR] [--element SELECTOR] [--clip x,y,w,h]`
|
|
3614
3652
|
// Returns { error } instead of throwing, so the CLI can print one clear line.
|
package/engine/server.mjs
CHANGED
|
@@ -20,7 +20,7 @@ import { resolve, dirname, join, basename } from 'node:path';
|
|
|
20
20
|
import { homedir } from 'node:os';
|
|
21
21
|
import { fileURLToPath } from 'node:url';
|
|
22
22
|
import { pathToFileURL } from 'node:url';
|
|
23
|
-
import { needsProjectFolder, folderLabel, chooseFolderScript, parseChosenFolder, buildFolderQuestion, resolveFolderAnswer, classifyFolderTarget, buildFolderInitConfirm, isFolderInitConfirmed, needsReviewPreference, buildReviewPreferenceQuestion, resolveReviewPreferenceAnswer, routeQuestionAnswer, notUnderstoodNote, parseRelocalizedQuestion, classifyAuthProbe, authBannerText, makeSigninChallenge, parseClaimResponse, isCommandOnPath, parseRequestedWorkspaceDir } from './lib.mjs';
|
|
23
|
+
import { needsProjectFolder, folderLabel, chooseFolderScript, parseChosenFolder, buildFolderQuestion, resolveFolderAnswer, classifyFolderTarget, buildFolderInitConfirm, isFolderInitConfirmed, needsReviewPreference, buildReviewPreferenceQuestion, resolveReviewPreferenceAnswer, routeQuestionAnswer, notUnderstoodNote, parseRelocalizedQuestion, classifyAuthProbe, authBannerText, makeSigninChallenge, parseClaimResponse, isCommandOnPath, hostReadiness, parseRequestedWorkspaceDir } from './lib.mjs';
|
|
24
24
|
import { parseStreamEvents, parseCodexEvents, buildCodexArgs, parsePlan, refinePlanTasks, canEditGoal, canDeleteGoal, shouldAskClarification, workerExitReason, classifyWorkerFailure, isForcedStop, taskStatusAfterVerify, workerResultText, taskCountsAsComplete, resolveWantsPR, resolveGoalSource, buildGoalSummary, buildReviewAttemptLedger, latestGoalOutcomeTask, buildDirtyWorkspacePrBlock, buildGoalProofMd, buildGoalPrBody, buildReviewSummaryPrompt, parseReviewSummary, buildReviewRuleSection, nextGoalStatus, isPrMerged, isPrApproved, reviewToDoneStatus, advanceReviewGoal, revertReviewGoal, approveGoal, dismissGoal, rejectGoal, reopenGoal, permissionModeFor, isPlanReview, nextAfterPlanApprove, GOAL_MODES, parseSkillFrontmatter, collectSkills, retestGoal, cancelRetestGoal, computeRetestOutcome, revertGoal, planRevertActions, archiveGoal, unarchiveGoal, undismissGoal, parseNumstat, truncateDiffText, sumUsage, resolveEntryUrl, rebasePreviewUrl, shouldCreateGoalPR, normalizePullRequestUrl, parseGitLog, diffNewCommits, replayQueueLog, reconcileOrphanGoals, reorderQueue, sortQueueByPriority, TASK_PRIORITIES, validateWorkflowColumns, DEFAULT_WORKFLOW_COLUMNS, validateReviewDefinition, DEFAULT_REVIEW_DEFINITION, resolveTestGate, buildEphemeralSeedLog, buildEphemeralSeedProjects, trimTaskActivityForState, buildAskContext, WORKER_TOOLS, workerPrompt, verifyCfAccessJwt, resolveIdentity, goalVisibleTo, clampParallelLimit, canStartMore, nextRunnableTasks, goalsConflict, detectConflicts, pickFoldTarget, autoFoldReviewsEnabled, parseGitUnifiedDiffLocations, hasTestRelevantChanges, parseFailingTestNames, classifyTestGate, classifyPrSafety, isInconclusiveTestRun, countInfraFlakes, classifyRunFailures, classifyVerifyGate, buildVerificationInfraError, verificationInfraErrorFrom, buildExecutionPlan, buildContextHandoffSummary, buildFailurePostmortem, appendFailureMemory, latestFailurePolicy, classifyChangeRisk, checkRunBudget, usageBudgetTokens, isRateLimited, nextResumeDelay, checkFreeTierLimit, resolveEntitlement, resolveCachedEntitlement, FREE_TIER_LIMITS, QUEUED_GOAL_STATUSES, verifyLicenseToken, licenseTokenPayload, shouldRefreshLicense, shouldEmitSetupCompleted, pickAnalyticsUid, shouldEmitFreeExhausted, detectRequestLanguage, testFailureReason, manualTestRetryPrompt, isNothingVerifiable, isNothingVerifiableForPR, isSuspiciouslyIncompleteDone, classifyComposerIntentHeuristic, detectPauseIntent, buildIntentPrompt, parseIntentResponse, buildBoardSnapshot, validateBoardSnapshot, boardIsEmpty, decideBoardPull, resolveConnectedAgents, pickAvailableAgent, pickUtilityAgent, utilityModel, liveTakeoverDecision, shouldOpenBrowserOnBoot, goalTaskTitle, buildGoalTask, shouldUsePlannerForGoal, RUN_DECL_FILE, REQUIREMENT_EVIDENCE_FILE, parseRequirementEvidenceDocument, parseRunDeclaration, SHOT_DIR, collectShotNames, parseGoalAddress, REPLY_OUTCOMES, buildGoalMessage, serializeGoalMessage, parseGoalMessages, computeInternalQualityMetrics, classifyInternalQualityTaskError, resolveWorkspaceMode, goalSessionFor, setGoalAgentSession, switchGoalAgentSession, parseApprovalRequest } from './lib.mjs';
|
|
25
25
|
import { migrateRequirementModel, validateRequirementModel } from './requirement-model.mjs';
|
|
26
26
|
import { buildManagerVerificationChecks, buildRequirementVerificationEvidence, mergeRequirementVerificationEvidence } from './requirement-verification.mjs';
|
|
@@ -3335,6 +3335,14 @@ function testNodePath(dir, dependencySourceDir = null) {
|
|
|
3335
3335
|
.filter(Boolean).filter(existsSync);
|
|
3336
3336
|
return [...new Set([...local, ...(process.env.NODE_PATH ? process.env.NODE_PATH.split(sep) : [])])].join(sep);
|
|
3337
3337
|
}
|
|
3338
|
+
// Advisory host capabilities for /api/state (see hostReadiness in lib.mjs). This
|
|
3339
|
+
// touches the filesystem, and /api/state is polled every couple of seconds, so
|
|
3340
|
+
// answer once: installing Chrome mid-session is not a thing to poll for, and a
|
|
3341
|
+
// restart is already how this app picks up a new environment.
|
|
3342
|
+
let _hostReadiness = null;
|
|
3343
|
+
function hostReadinessNow() {
|
|
3344
|
+
return (_hostReadiness ??= hostReadiness({ platform: process.platform, env: process.env, existsFn: existsSync }));
|
|
3345
|
+
}
|
|
3338
3346
|
function testEnvironmentPreflight(dir, dependencySourceDir = null) {
|
|
3339
3347
|
const nodePath = testNodePath(dir, dependencySourceDir);
|
|
3340
3348
|
const sources = nodePath ? nodePath.split(process.platform === 'win32' ? ';' : ':') : [];
|
|
@@ -4367,7 +4375,7 @@ const server = createServer(async (req, res) => {
|
|
|
4367
4375
|
const dirty = projectDirtyInfo(p.dir);
|
|
4368
4376
|
return { ...p, ...(branch ? { branch } : {}), ...dirty };
|
|
4369
4377
|
});
|
|
4370
|
-
return json(res, 200, { projects: projectsWithBranch, goals: visibleGoals, tasks: trimTaskActivityForState(visibleTasks), models: MODELS, agentModels: { 'claude-code': MODELS, codex: CODEX_MODELS }, agentEfforts: { 'claude-code': CLAUDE_EFFORTS, codex: CODEX_EFFORTS }, agents: AVAILABLE_AGENTS, connectCommand, queueOrder, externalActivity, workflowColumns: projectColumns, reviewDefinitions: projectReviewDefs, runningCounts, parallelLimits, uiVersion: uiVersion(), billing, auth: publicAuth() });
|
|
4378
|
+
return json(res, 200, { projects: projectsWithBranch, goals: visibleGoals, tasks: trimTaskActivityForState(visibleTasks), models: MODELS, agentModels: { 'claude-code': MODELS, codex: CODEX_MODELS }, agentEfforts: { 'claude-code': CLAUDE_EFFORTS, codex: CODEX_EFFORTS }, agents: AVAILABLE_AGENTS, connectCommand, queueOrder, externalActivity, workflowColumns: projectColumns, reviewDefinitions: projectReviewDefs, runningCounts, parallelLimits, uiVersion: uiVersion(), billing, hostReadiness: hostReadinessNow(), auth: publicAuth() });
|
|
4371
4379
|
}
|
|
4372
4380
|
|
|
4373
4381
|
// Read-only stability snapshot: separates implementation failures from
|
package/package.json
CHANGED