@opengsd/gsd-pi 1.1.1-dev.3ea310e → 1.1.1-dev.74e8dd1
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/dist/resources/.managed-resources-content-hash +1 -1
- package/dist/resources/extensions/gsd/auto/phases.js +4 -3
- package/dist/resources/extensions/gsd/auto-dashboard.js +15 -4
- package/dist/resources/extensions/gsd/auto-post-unit.js +111 -5
- package/dist/resources/extensions/gsd/auto-prompts.js +9 -0
- package/dist/resources/extensions/gsd/auto-start.js +41 -12
- package/dist/resources/extensions/gsd/auto-unit-tool-scope.js +2 -1
- package/dist/resources/extensions/gsd/auto.js +3 -3
- package/dist/resources/extensions/gsd/bootstrap/db-tools.js +79 -0
- package/dist/resources/extensions/gsd/bootstrap/exec-tools.js +43 -0
- package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +30 -9
- package/dist/resources/extensions/gsd/bootstrap/write-gate.js +16 -10
- package/dist/resources/extensions/gsd/commands/handlers/core.js +1 -1
- package/dist/resources/extensions/gsd/commands-prefs-wizard.js +3 -1
- package/dist/resources/extensions/gsd/commands-verdict.js +1 -1
- package/dist/resources/extensions/gsd/config-overlay.js +2 -1
- package/dist/resources/extensions/gsd/error-classifier.js +2 -1
- package/dist/resources/extensions/gsd/exec-sandbox.js +2 -0
- package/dist/resources/extensions/gsd/prompts/run-uat.md +10 -4
- package/dist/resources/extensions/gsd/prompts/system.md +3 -1
- package/dist/resources/extensions/gsd/safety/destructive-guard.js +3 -0
- package/dist/resources/extensions/gsd/skill-activation.js +20 -3
- package/dist/resources/extensions/gsd/state-reconciliation/drift/roadmap.js +18 -1
- package/dist/resources/extensions/gsd/state-reconciliation/index.js +6 -0
- package/dist/resources/extensions/gsd/state.js +1 -1
- package/dist/resources/extensions/gsd/tools/exec-tool.js +109 -0
- package/dist/resources/extensions/gsd/tools/workflow-tool-executors.js +366 -3
- package/dist/resources/extensions/gsd/unit-context-manifest.js +8 -3
- package/dist/resources/extensions/gsd/validation-block-guard.js +2 -0
- package/dist/resources/extensions/gsd/workflow-mcp-auto-prep.js +1 -1
- package/dist/resources/extensions/gsd/workflow-mcp.js +5 -1
- package/dist/web/standalone/.next/BUILD_ID +1 -1
- package/dist/web/standalone/.next/app-path-routes-manifest.json +6 -6
- package/dist/web/standalone/.next/build-manifest.json +2 -2
- package/dist/web/standalone/.next/prerender-manifest.json +3 -3
- package/dist/web/standalone/.next/server/app/_global-error.html +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/index.html +1 -1
- package/dist/web/standalone/.next/server/app/index.rsc +1 -1
- package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app-paths-manifest.json +6 -6
- package/dist/web/standalone/.next/server/chunks/8357.js +1 -1
- package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
- package/dist/web/standalone/.next/server/pages/404.html +1 -1
- package/dist/web/standalone/.next/server/pages/500.html +1 -1
- package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
- package/package.json +2 -2
- package/packages/cloud-mcp-gateway/package.json +2 -2
- package/packages/contracts/dist/workflow.d.ts +14 -0
- package/packages/contracts/dist/workflow.d.ts.map +1 -1
- package/packages/contracts/dist/workflow.js +16 -0
- package/packages/contracts/dist/workflow.js.map +1 -1
- package/packages/contracts/package.json +1 -1
- package/packages/daemon/package.json +4 -4
- package/packages/gsd-agent-core/package.json +5 -5
- package/packages/gsd-agent-modes/dist/modes/interactive/components/settings-selector.d.ts +2 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/components/settings-selector.js +10 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/components/settings-selector.js.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller.d.ts +1 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller.d.ts.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller.js +69 -31
- package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller.js.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode-class-constants.d.ts +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode-class-constants.d.ts.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode-class-constants.js +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode-class-constants.js.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode.js +1 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-selectors-settings.d.ts.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-selectors-settings.js +5 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-selectors-settings.js.map +1 -1
- package/packages/gsd-agent-modes/package.json +7 -7
- package/packages/mcp-server/dist/workflow-tools.d.ts.map +1 -1
- package/packages/mcp-server/dist/workflow-tools.js +82 -0
- package/packages/mcp-server/dist/workflow-tools.js.map +1 -1
- package/packages/mcp-server/package.json +3 -3
- package/packages/native/package.json +1 -1
- package/packages/pi-agent-core/package.json +1 -1
- package/packages/pi-ai/dist/image-models.generated.d.ts +15 -0
- package/packages/pi-ai/dist/image-models.generated.d.ts.map +1 -1
- package/packages/pi-ai/dist/image-models.generated.js +15 -0
- package/packages/pi-ai/dist/image-models.generated.js.map +1 -1
- package/packages/pi-ai/dist/models.generated.d.ts +35 -1
- package/packages/pi-ai/dist/models.generated.d.ts.map +1 -1
- package/packages/pi-ai/dist/models.generated.js +53 -19
- package/packages/pi-ai/dist/models.generated.js.map +1 -1
- package/packages/pi-ai/package.json +1 -1
- package/packages/pi-coding-agent/dist/core/settings-manager.d.ts +3 -0
- package/packages/pi-coding-agent/dist/core/settings-manager.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/settings-manager.js +11 -0
- package/packages/pi-coding-agent/dist/core/settings-manager.js.map +1 -1
- package/packages/pi-coding-agent/package.json +7 -7
- package/packages/pi-tui/dist/terminal.d.ts +1 -0
- package/packages/pi-tui/dist/terminal.d.ts.map +1 -1
- package/packages/pi-tui/dist/terminal.js +8 -4
- package/packages/pi-tui/dist/terminal.js.map +1 -1
- package/packages/pi-tui/package.json +1 -1
- package/packages/rpc-client/package.json +2 -2
- package/pkg/package.json +1 -1
- package/src/resources/extensions/gsd/auto/phases.ts +5 -3
- package/src/resources/extensions/gsd/auto-dashboard.ts +16 -4
- package/src/resources/extensions/gsd/auto-post-unit.ts +136 -5
- package/src/resources/extensions/gsd/auto-prompts.ts +9 -0
- package/src/resources/extensions/gsd/auto-start.ts +54 -14
- package/src/resources/extensions/gsd/auto-unit-tool-scope.ts +2 -1
- package/src/resources/extensions/gsd/auto.ts +3 -2
- package/src/resources/extensions/gsd/bootstrap/db-tools.ts +86 -0
- package/src/resources/extensions/gsd/bootstrap/exec-tools.ts +51 -0
- package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +51 -14
- package/src/resources/extensions/gsd/bootstrap/write-gate.ts +21 -10
- package/src/resources/extensions/gsd/commands/handlers/core.ts +1 -1
- package/src/resources/extensions/gsd/commands-prefs-wizard.ts +4 -1
- package/src/resources/extensions/gsd/commands-verdict.ts +1 -1
- package/src/resources/extensions/gsd/config-overlay.ts +3 -1
- package/src/resources/extensions/gsd/error-classifier.ts +2 -1
- package/src/resources/extensions/gsd/exec-sandbox.ts +4 -0
- package/src/resources/extensions/gsd/preferences-types.ts +1 -1
- package/src/resources/extensions/gsd/prompts/run-uat.md +10 -4
- package/src/resources/extensions/gsd/prompts/system.md +3 -1
- package/src/resources/extensions/gsd/safety/destructive-guard.ts +3 -0
- package/src/resources/extensions/gsd/skill-activation.ts +20 -2
- package/src/resources/extensions/gsd/state-reconciliation/drift/roadmap.ts +20 -0
- package/src/resources/extensions/gsd/state-reconciliation/index.ts +6 -0
- package/src/resources/extensions/gsd/state-reconciliation/types.ts +1 -0
- package/src/resources/extensions/gsd/state.ts +1 -1
- package/src/resources/extensions/gsd/tests/auto-dashboard.test.ts +51 -0
- package/src/resources/extensions/gsd/tests/auto-start-orphan-bootstrap.test.ts +16 -3
- package/src/resources/extensions/gsd/tests/commands-dispatcher-validation-block.test.ts +38 -3
- package/src/resources/extensions/gsd/tests/commands-verdict.test.ts +6 -2
- package/src/resources/extensions/gsd/tests/derive-state-db.test.ts +8 -0
- package/src/resources/extensions/gsd/tests/derive-state-helpers.test.ts +8 -0
- package/src/resources/extensions/gsd/tests/exec-sandbox.test.ts +18 -0
- package/src/resources/extensions/gsd/tests/exec-tool.test.ts +69 -0
- package/src/resources/extensions/gsd/tests/parallel-skill-prompt-integration.test.ts +54 -7
- package/src/resources/extensions/gsd/tests/prompt-contracts.test.ts +10 -0
- package/src/resources/extensions/gsd/tests/provider-errors.test.ts +18 -1
- package/src/resources/extensions/gsd/tests/reactive-executor.test.ts +36 -0
- package/src/resources/extensions/gsd/tests/register-hooks-depth-verification.test.ts +35 -0
- package/src/resources/extensions/gsd/tests/restore-tools-after-discuss.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/skill-activation.test.ts +55 -0
- package/src/resources/extensions/gsd/tests/state-reconciliation-drift.test.ts +52 -0
- package/src/resources/extensions/gsd/tests/token-tool-gating.test.ts +84 -10
- package/src/resources/extensions/gsd/tests/tool-naming.test.ts +12 -2
- package/src/resources/extensions/gsd/tests/tui-header-lifecycle.test.ts +29 -6
- package/src/resources/extensions/gsd/tests/unit-context-manifest.test.ts +29 -6
- package/src/resources/extensions/gsd/tests/validation-block-guard.test.ts +21 -0
- package/src/resources/extensions/gsd/tests/workflow-mcp-auto-prep.test.ts +2 -2
- package/src/resources/extensions/gsd/tests/workflow-tool-executors.test.ts +83 -0
- package/src/resources/extensions/gsd/tests/write-gate-planning-unit.test.ts +25 -0
- package/src/resources/extensions/gsd/tools/exec-tool.ts +130 -0
- package/src/resources/extensions/gsd/tools/workflow-tool-executors.ts +440 -2
- package/src/resources/extensions/gsd/unit-context-manifest.ts +14 -5
- package/src/resources/extensions/gsd/validation-block-guard.ts +2 -0
- package/src/resources/extensions/gsd/workflow-mcp-auto-prep.ts +1 -1
- package/src/resources/extensions/gsd/workflow-mcp.ts +5 -1
- /package/dist/web/standalone/.next/static/{xACmObbrDjwLriepRgaa9 → eRWf-RI9bzbrwEurm_3uI}/_buildManifest.js +0 -0
- /package/dist/web/standalone/.next/static/{xACmObbrDjwLriepRgaa9 → eRWf-RI9bzbrwEurm_3uI}/_ssgManifest.js +0 -0
|
@@ -3,13 +3,13 @@
|
|
|
3
3
|
import { ensureDbOpen } from "../bootstrap/dynamic-tools.js";
|
|
4
4
|
import { sanitizeCompleteMilestoneParams } from "../bootstrap/sanitize-complete-milestone.js";
|
|
5
5
|
import { loadWriteGateSnapshot, shouldBlockContextArtifactSaveInSnapshot, shouldBlockRootArtifactSaveInSnapshot } from "../bootstrap/write-gate.js";
|
|
6
|
-
import { getActiveRequirements, insertMilestone, getMilestone, getSliceStatusSummary, getSliceTaskCounts, readTransaction, saveGateResult, } from "../gsd-db.js";
|
|
6
|
+
import { getActiveRequirements, insertMilestone, getMilestone, getSliceStatusSummary, getSliceTaskCounts, insertGateRun, readTransaction, saveGateResult, upsertQualityGate, } from "../gsd-db.js";
|
|
7
7
|
import { GATE_REGISTRY } from "../gate-registry.js";
|
|
8
8
|
import { generateRequirementsMd, saveArtifactToDb } from "../db-writer.js";
|
|
9
9
|
import { clearPathCache, resolveGsdPathContract, resolveMilestoneFile, resolveSliceFile } from "../paths.js";
|
|
10
10
|
import { saveFile, clearParseCache } from "../files.js";
|
|
11
|
-
import { unlinkSync } from "node:fs";
|
|
12
|
-
import { join } from "node:path";
|
|
11
|
+
import { existsSync, readdirSync, readFileSync, unlinkSync } from "node:fs";
|
|
12
|
+
import { isAbsolute, join, resolve } from "node:path";
|
|
13
13
|
import { handleCompleteMilestone } from "./complete-milestone.js";
|
|
14
14
|
import { handleCompleteTask } from "./complete-task.js";
|
|
15
15
|
import { handleCompleteSlice } from "./complete-slice.js";
|
|
@@ -26,6 +26,7 @@ import { invalidateStateCache } from "../state.js";
|
|
|
26
26
|
import { loadEffectiveGSDPreferences } from "../preferences.js";
|
|
27
27
|
import { parseProject } from "../schemas/parsers.js";
|
|
28
28
|
import { getAutoRuntimeSnapshot } from "../auto-runtime-state.js";
|
|
29
|
+
import { canonicalWorkflowToolName, parseMcpToolName, RUN_UAT_FORBIDDEN_TOOL_NAMES, RUN_UAT_WORKFLOW_TOOL_NAMES, } from "../tool-presentation-plan.js";
|
|
29
30
|
export const SUPPORTED_SUMMARY_ARTIFACT_TYPES = [
|
|
30
31
|
"SUMMARY",
|
|
31
32
|
"RESEARCH",
|
|
@@ -775,6 +776,368 @@ export async function executeSaveGateResult(params, basePath = process.cwd()) {
|
|
|
775
776
|
};
|
|
776
777
|
}
|
|
777
778
|
}
|
|
779
|
+
function errorResult(operation, message, error) {
|
|
780
|
+
return {
|
|
781
|
+
content: [{ type: "text", text: `Error: ${message}` }],
|
|
782
|
+
details: { operation, error },
|
|
783
|
+
isError: true,
|
|
784
|
+
};
|
|
785
|
+
}
|
|
786
|
+
function isNonEmptyString(value) {
|
|
787
|
+
return typeof value === "string" && value.trim().length > 0;
|
|
788
|
+
}
|
|
789
|
+
function ensureUatRequiredFields(params) {
|
|
790
|
+
if (!isNonEmptyString(params.milestoneId))
|
|
791
|
+
return "milestoneId is required";
|
|
792
|
+
if (!isNonEmptyString(params.sliceId))
|
|
793
|
+
return "sliceId is required";
|
|
794
|
+
if (!isNonEmptyString(params.uatType))
|
|
795
|
+
return "uatType is required";
|
|
796
|
+
if (!["PASS", "FAIL", "PARTIAL"].includes(params.verdict))
|
|
797
|
+
return "verdict must be PASS, FAIL, or PARTIAL";
|
|
798
|
+
if (!Array.isArray(params.checks) || params.checks.length === 0)
|
|
799
|
+
return "checks must contain at least one UAT check";
|
|
800
|
+
if (!params.presentation || !Array.isArray(params.presentation.presentedTools))
|
|
801
|
+
return "presentation.presentedTools is required";
|
|
802
|
+
if (!Array.isArray(params.presentation.blockedTools))
|
|
803
|
+
return "presentation.blockedTools is required";
|
|
804
|
+
return null;
|
|
805
|
+
}
|
|
806
|
+
function approvedEvidenceRoots(basePath) {
|
|
807
|
+
const contract = resolveGsdPathContract(basePath);
|
|
808
|
+
return [contract.worktreeGsd, contract.projectGsd].filter((root) => typeof root === "string");
|
|
809
|
+
}
|
|
810
|
+
function approvedBrowserArtifactRoots(basePath) {
|
|
811
|
+
const contract = resolveGsdPathContract(basePath);
|
|
812
|
+
const roots = [contract.workRoot, contract.projectRoot].map((root) => join(root, ".artifacts", "browser"));
|
|
813
|
+
return [...new Set(roots)];
|
|
814
|
+
}
|
|
815
|
+
function pathStartsWithin(parent, target) {
|
|
816
|
+
const normalizedParent = parent.replace(/\\/g, "/").replace(/\/+$/, "");
|
|
817
|
+
const normalizedTarget = target.replace(/\\/g, "/").replace(/\/+$/, "");
|
|
818
|
+
return normalizedTarget === normalizedParent || normalizedTarget.startsWith(`${normalizedParent}/`);
|
|
819
|
+
}
|
|
820
|
+
function pushUnique(paths, candidate) {
|
|
821
|
+
if (!paths.includes(candidate))
|
|
822
|
+
paths.push(candidate);
|
|
823
|
+
}
|
|
824
|
+
function execMetaPathCandidates(basePath, ref) {
|
|
825
|
+
const trimmed = ref.trim();
|
|
826
|
+
const candidates = [];
|
|
827
|
+
const execDirs = approvedEvidenceRoots(basePath).map((root) => join(root, "exec"));
|
|
828
|
+
const normalizedRef = trimmed.replace(/\\/g, "/");
|
|
829
|
+
const pathLike = normalizedRef.endsWith(".meta.json") || normalizedRef.includes("/.gsd/exec/");
|
|
830
|
+
if (pathLike) {
|
|
831
|
+
const rawPath = isAbsolute(trimmed) ? resolve(trimmed) : resolve(basePath, trimmed);
|
|
832
|
+
pushUnique(candidates, rawPath);
|
|
833
|
+
const relativeExecMarker = ".gsd/exec/";
|
|
834
|
+
const markerIndex = normalizedRef.indexOf(relativeExecMarker);
|
|
835
|
+
if (markerIndex >= 0) {
|
|
836
|
+
const execRelative = normalizedRef.slice(markerIndex + relativeExecMarker.length);
|
|
837
|
+
for (const execDir of execDirs) {
|
|
838
|
+
pushUnique(candidates, join(execDir, execRelative));
|
|
839
|
+
}
|
|
840
|
+
}
|
|
841
|
+
return candidates.filter((candidate) => execDirs.some((execDir) => pathStartsWithin(execDir, candidate)));
|
|
842
|
+
}
|
|
843
|
+
for (const execDir of execDirs) {
|
|
844
|
+
pushUnique(candidates, join(execDir, `${trimmed}.meta.json`));
|
|
845
|
+
}
|
|
846
|
+
return candidates;
|
|
847
|
+
}
|
|
848
|
+
function resolveExecMetaPath(basePath, ref) {
|
|
849
|
+
for (const candidate of execMetaPathCandidates(basePath, ref)) {
|
|
850
|
+
if (existsSync(candidate))
|
|
851
|
+
return candidate;
|
|
852
|
+
}
|
|
853
|
+
return null;
|
|
854
|
+
}
|
|
855
|
+
function evidencePathIsApproved(basePath, ref) {
|
|
856
|
+
const normalizedRef = ref.replace(/\\/g, "/");
|
|
857
|
+
if (normalizedRef.startsWith(".gsd/exec/") || normalizedRef.startsWith(".gsd/uat/"))
|
|
858
|
+
return true;
|
|
859
|
+
if (normalizedRef.startsWith(".artifacts/browser/")) {
|
|
860
|
+
const resolvedRef = resolve(basePath, ref);
|
|
861
|
+
return approvedBrowserArtifactRoots(basePath).some((root) => pathStartsWithin(root, resolvedRef));
|
|
862
|
+
}
|
|
863
|
+
const gsdEvidenceApproved = approvedEvidenceRoots(basePath).some((root) => {
|
|
864
|
+
return pathStartsWithin(join(root, "exec"), ref) || pathStartsWithin(join(root, "uat"), ref);
|
|
865
|
+
});
|
|
866
|
+
if (gsdEvidenceApproved)
|
|
867
|
+
return true;
|
|
868
|
+
return approvedBrowserArtifactRoots(basePath).some((root) => pathStartsWithin(root, ref));
|
|
869
|
+
}
|
|
870
|
+
function validateEvidenceRef(basePath, evidence) {
|
|
871
|
+
if (!isNonEmptyString(evidence.ref))
|
|
872
|
+
return "evidence.ref is required";
|
|
873
|
+
if (evidence.kind === "gsd_uat_exec" || evidence.kind === "gsd_exec") {
|
|
874
|
+
const path = resolveExecMetaPath(basePath, evidence.ref.trim());
|
|
875
|
+
if (!path)
|
|
876
|
+
return `missing gsd_exec metadata for evidence id "${evidence.ref}"`;
|
|
877
|
+
if (evidence.kind === "gsd_uat_exec") {
|
|
878
|
+
try {
|
|
879
|
+
const meta = JSON.parse(readFileSync(path, "utf-8"));
|
|
880
|
+
if (meta.metadata?.kind !== "uat_exec")
|
|
881
|
+
return `evidence id "${evidence.ref}" is not typed as uat_exec`;
|
|
882
|
+
}
|
|
883
|
+
catch {
|
|
884
|
+
return `invalid gsd_exec metadata JSON for evidence id "${evidence.ref}"`;
|
|
885
|
+
}
|
|
886
|
+
}
|
|
887
|
+
return null;
|
|
888
|
+
}
|
|
889
|
+
if (evidence.kind === "url") {
|
|
890
|
+
try {
|
|
891
|
+
const parsed = new URL(evidence.ref);
|
|
892
|
+
return parsed.protocol === "http:" || parsed.protocol === "https:"
|
|
893
|
+
? null
|
|
894
|
+
: `invalid URL evidence ref "${evidence.ref}"`;
|
|
895
|
+
}
|
|
896
|
+
catch {
|
|
897
|
+
return `invalid URL evidence ref "${evidence.ref}"`;
|
|
898
|
+
}
|
|
899
|
+
}
|
|
900
|
+
return evidencePathIsApproved(basePath, evidence.ref)
|
|
901
|
+
? null
|
|
902
|
+
: `evidence ref "${evidence.ref}" is outside approved evidence locations`;
|
|
903
|
+
}
|
|
904
|
+
function validateUatChecks(basePath, params) {
|
|
905
|
+
for (const check of params.checks) {
|
|
906
|
+
if (!isNonEmptyString(check.id))
|
|
907
|
+
return "every check must have a non-empty id";
|
|
908
|
+
if (!isNonEmptyString(check.description))
|
|
909
|
+
return `check ${check.id} must have a description`;
|
|
910
|
+
if (!["artifact", "runtime", "browser", "human-follow-up"].includes(check.mode)) {
|
|
911
|
+
return `check ${check.id} has invalid mode "${check.mode}"`;
|
|
912
|
+
}
|
|
913
|
+
if (!["PASS", "FAIL", "NEEDS-HUMAN"].includes(check.result)) {
|
|
914
|
+
return `check ${check.id} has invalid result "${check.result}"`;
|
|
915
|
+
}
|
|
916
|
+
if (check.result === "PASS" || check.result === "FAIL") {
|
|
917
|
+
if (!Array.isArray(check.evidence) || check.evidence.length === 0) {
|
|
918
|
+
return `check ${check.id} is ${check.result} but has no objective evidence`;
|
|
919
|
+
}
|
|
920
|
+
for (const evidence of check.evidence) {
|
|
921
|
+
const error = validateEvidenceRef(basePath, evidence);
|
|
922
|
+
if (error)
|
|
923
|
+
return `check ${check.id}: ${error}`;
|
|
924
|
+
}
|
|
925
|
+
}
|
|
926
|
+
else if (!isNonEmptyString(check.notes)) {
|
|
927
|
+
return `check ${check.id} is NEEDS-HUMAN but has no manual instruction or reason`;
|
|
928
|
+
}
|
|
929
|
+
}
|
|
930
|
+
return null;
|
|
931
|
+
}
|
|
932
|
+
function validateUatMode(params) {
|
|
933
|
+
const modes = new Set(params.checks.map((check) => check.mode));
|
|
934
|
+
const hasHuman = params.checks.some((check) => check.result === "NEEDS-HUMAN");
|
|
935
|
+
if (hasHuman &&
|
|
936
|
+
params.verdict === "PASS" &&
|
|
937
|
+
!["human-experience", "mixed", "live-runtime"].includes(params.uatType) &&
|
|
938
|
+
!params.checks.every((check) => check.result !== "NEEDS-HUMAN" || check.nonAutomatable === true)) {
|
|
939
|
+
return "NEEDS-HUMAN checks can only coexist with PASS for human-experience, mixed, live-runtime, or explicitly non-automatable checks";
|
|
940
|
+
}
|
|
941
|
+
if (params.uatType === "runtime-executable" && !modes.has("runtime")) {
|
|
942
|
+
return "runtime-executable UAT requires at least one runtime check";
|
|
943
|
+
}
|
|
944
|
+
if (params.uatType === "browser-executable" && !modes.has("browser")) {
|
|
945
|
+
return "browser-executable UAT requires at least one browser check";
|
|
946
|
+
}
|
|
947
|
+
if (params.uatType === "live-runtime" && !modes.has("runtime") && !modes.has("browser")) {
|
|
948
|
+
return "live-runtime UAT requires runtime or browser evidence";
|
|
949
|
+
}
|
|
950
|
+
if (params.uatType === "artifact-driven" && hasHuman && params.verdict === "PASS") {
|
|
951
|
+
return "artifact-driven UAT cannot PASS with human-only checks";
|
|
952
|
+
}
|
|
953
|
+
return null;
|
|
954
|
+
}
|
|
955
|
+
function validateCanonicalPresentation(params) {
|
|
956
|
+
const aliasHints = {
|
|
957
|
+
gsd_save_summary: "gsd_summary_save",
|
|
958
|
+
gsd_complete_task: "gsd_task_complete",
|
|
959
|
+
gsd_complete_slice: "gsd_slice_complete",
|
|
960
|
+
gsd_milestone_complete: "gsd_complete_milestone",
|
|
961
|
+
};
|
|
962
|
+
for (const toolName of params.presentation.presentedTools) {
|
|
963
|
+
const baseName = parseMcpToolName(toolName)?.tool ?? toolName;
|
|
964
|
+
const canonical = aliasHints[baseName];
|
|
965
|
+
if (canonical)
|
|
966
|
+
return `presentation tool "${toolName}" uses an alias; use canonical "${canonical}"`;
|
|
967
|
+
}
|
|
968
|
+
const presentedCanonical = new Set(params.presentation.presentedTools.map((toolName) => canonicalWorkflowToolName(parseMcpToolName(toolName)?.tool ?? toolName)));
|
|
969
|
+
for (const requiredTool of RUN_UAT_WORKFLOW_TOOL_NAMES) {
|
|
970
|
+
if (!presentedCanonical.has(requiredTool)) {
|
|
971
|
+
return `presentation is missing required UAT tool "${requiredTool}"`;
|
|
972
|
+
}
|
|
973
|
+
}
|
|
974
|
+
const forbiddenCanonical = new Set(RUN_UAT_FORBIDDEN_TOOL_NAMES
|
|
975
|
+
.filter((toolName) => !toolName.includes("*"))
|
|
976
|
+
.map((toolName) => canonicalWorkflowToolName(parseMcpToolName(toolName)?.tool ?? toolName)));
|
|
977
|
+
for (const toolName of params.presentation.presentedTools) {
|
|
978
|
+
const canonical = canonicalWorkflowToolName(parseMcpToolName(toolName)?.tool ?? toolName);
|
|
979
|
+
if (toolName === "mcp__gsd-workflow__*" || forbiddenCanonical.has(canonical)) {
|
|
980
|
+
return `presentation includes forbidden run-uat tool "${toolName}"`;
|
|
981
|
+
}
|
|
982
|
+
}
|
|
983
|
+
const blockedCanonical = new Set(params.presentation.blockedTools.map((entry) => canonicalWorkflowToolName(parseMcpToolName(entry.name)?.tool ?? entry.name)));
|
|
984
|
+
for (const blockedTool of ["gsd_exec", "gsd_summary_save", "gsd_save_gate_result"]) {
|
|
985
|
+
if (!blockedCanonical.has(blockedTool)) {
|
|
986
|
+
return `presentation must record "${blockedTool}" as blocked during run-uat`;
|
|
987
|
+
}
|
|
988
|
+
}
|
|
989
|
+
return null;
|
|
990
|
+
}
|
|
991
|
+
function nextUatAttempt(basePath, milestoneId, sliceId) {
|
|
992
|
+
const contract = resolveGsdPathContract(basePath);
|
|
993
|
+
const dir = join(contract.projectGsd, "uat", milestoneId, sliceId);
|
|
994
|
+
if (!existsSync(dir))
|
|
995
|
+
return 1;
|
|
996
|
+
let max = 0;
|
|
997
|
+
for (const entry of readdirSync(dir)) {
|
|
998
|
+
const match = /^attempt-(\d+)\.json$/.exec(entry);
|
|
999
|
+
if (match)
|
|
1000
|
+
max = Math.max(max, Number(match[1]));
|
|
1001
|
+
}
|
|
1002
|
+
return max + 1;
|
|
1003
|
+
}
|
|
1004
|
+
function escapeMarkdownTableCell(value) {
|
|
1005
|
+
return String(value ?? "")
|
|
1006
|
+
.replace(/[\\|]/g, (char) => `\\${char}`)
|
|
1007
|
+
.replace(/\r?\n/g, "<br>");
|
|
1008
|
+
}
|
|
1009
|
+
function renderUatAssessment(params, attempt, gateVerdict) {
|
|
1010
|
+
const lines = [
|
|
1011
|
+
"---",
|
|
1012
|
+
`sliceId: ${params.sliceId}`,
|
|
1013
|
+
`uatType: ${params.uatType}`,
|
|
1014
|
+
`verdict: ${params.verdict}`,
|
|
1015
|
+
`attempt: ${attempt}`,
|
|
1016
|
+
`date: ${new Date().toISOString()}`,
|
|
1017
|
+
"---",
|
|
1018
|
+
"",
|
|
1019
|
+
`# UAT Result - ${params.sliceId}`,
|
|
1020
|
+
"",
|
|
1021
|
+
"## Checks",
|
|
1022
|
+
"",
|
|
1023
|
+
"| Check | Mode | Result | Evidence | Notes |",
|
|
1024
|
+
"|-------|------|--------|----------|-------|",
|
|
1025
|
+
...params.checks.map((check) => {
|
|
1026
|
+
const evidence = (check.evidence ?? []).map((entry) => `${entry.kind}:${entry.ref}`).join("<br>") || "-";
|
|
1027
|
+
return `| ${escapeMarkdownTableCell(check.description)} | ${escapeMarkdownTableCell(check.mode)} | ${escapeMarkdownTableCell(check.result)} | ${escapeMarkdownTableCell(evidence)} | ${escapeMarkdownTableCell(check.notes)} |`;
|
|
1028
|
+
}),
|
|
1029
|
+
"",
|
|
1030
|
+
"## Overall Verdict",
|
|
1031
|
+
"",
|
|
1032
|
+
`${params.verdict} - ${params.notes ?? "UAT result saved."}`,
|
|
1033
|
+
"",
|
|
1034
|
+
"## Tool Presentation",
|
|
1035
|
+
"",
|
|
1036
|
+
"```json",
|
|
1037
|
+
JSON.stringify(params.presentation, null, 2),
|
|
1038
|
+
"```",
|
|
1039
|
+
"",
|
|
1040
|
+
"## Gate",
|
|
1041
|
+
"",
|
|
1042
|
+
`Aggregate UAT gate saved as ${gateVerdict}.`,
|
|
1043
|
+
];
|
|
1044
|
+
return `${lines.join("\n")}\n`;
|
|
1045
|
+
}
|
|
1046
|
+
async function saveUatAttemptArtifact(basePath, params, attempt) {
|
|
1047
|
+
const contract = resolveGsdPathContract(basePath);
|
|
1048
|
+
const relativePath = `uat/${params.milestoneId}/${params.sliceId}/attempt-${attempt}.json`;
|
|
1049
|
+
await saveFile(join(contract.projectGsd, relativePath), `${JSON.stringify({ ...params, attempt }, null, 2)}\n`);
|
|
1050
|
+
return relativePath;
|
|
1051
|
+
}
|
|
1052
|
+
export async function executeUatResultSave(params, basePath = process.cwd()) {
|
|
1053
|
+
const dbAvailable = await ensureDbOpen(basePath);
|
|
1054
|
+
if (!dbAvailable)
|
|
1055
|
+
return errorResult("save_uat_result", "GSD database is not available.", "db_unavailable");
|
|
1056
|
+
const requiredError = ensureUatRequiredFields(params);
|
|
1057
|
+
if (requiredError)
|
|
1058
|
+
return errorResult("save_uat_result", requiredError, "invalid_params");
|
|
1059
|
+
const presentationError = validateCanonicalPresentation(params);
|
|
1060
|
+
if (presentationError)
|
|
1061
|
+
return errorResult("save_uat_result", presentationError, "alias_tool_name");
|
|
1062
|
+
const checkError = validateUatChecks(basePath, params);
|
|
1063
|
+
if (checkError)
|
|
1064
|
+
return errorResult("save_uat_result", checkError, "invalid_evidence");
|
|
1065
|
+
const modeError = validateUatMode(params);
|
|
1066
|
+
if (modeError)
|
|
1067
|
+
return errorResult("save_uat_result", modeError, "uat_mode_mismatch");
|
|
1068
|
+
try {
|
|
1069
|
+
const attempt = params.attempt === "auto" || params.attempt === undefined
|
|
1070
|
+
? nextUatAttempt(basePath, params.milestoneId, params.sliceId)
|
|
1071
|
+
: typeof params.attempt === "string"
|
|
1072
|
+
? Number.parseInt(params.attempt, 10)
|
|
1073
|
+
: params.attempt;
|
|
1074
|
+
if (!Number.isInteger(attempt) || attempt < 1) {
|
|
1075
|
+
return errorResult("save_uat_result", "attempt must be a positive integer or auto", "invalid_attempt");
|
|
1076
|
+
}
|
|
1077
|
+
const gateVerdict = params.verdict === "PASS" ? "pass" : "flag";
|
|
1078
|
+
const rationale = params.notes ?? `UAT ${params.verdict} for ${params.sliceId}.`;
|
|
1079
|
+
const assessment = renderUatAssessment(params, attempt, gateVerdict);
|
|
1080
|
+
const summary = await executeSummarySave({
|
|
1081
|
+
milestone_id: params.milestoneId,
|
|
1082
|
+
slice_id: params.sliceId,
|
|
1083
|
+
artifact_type: "ASSESSMENT",
|
|
1084
|
+
content: assessment,
|
|
1085
|
+
}, basePath);
|
|
1086
|
+
if (summary.isError)
|
|
1087
|
+
return summary;
|
|
1088
|
+
const attemptPath = await saveUatAttemptArtifact(basePath, params, attempt);
|
|
1089
|
+
const evaluatedAt = new Date().toISOString();
|
|
1090
|
+
upsertQualityGate({
|
|
1091
|
+
milestoneId: params.milestoneId,
|
|
1092
|
+
sliceId: params.sliceId,
|
|
1093
|
+
gateId: "UAT",
|
|
1094
|
+
scope: "slice",
|
|
1095
|
+
taskId: "",
|
|
1096
|
+
status: "complete",
|
|
1097
|
+
verdict: gateVerdict,
|
|
1098
|
+
rationale,
|
|
1099
|
+
findings: assessment,
|
|
1100
|
+
evaluatedAt,
|
|
1101
|
+
});
|
|
1102
|
+
insertGateRun({
|
|
1103
|
+
traceId: `uat:${params.milestoneId}:${params.sliceId}`,
|
|
1104
|
+
turnId: `uat:${params.sliceId}:attempt-${attempt}`,
|
|
1105
|
+
gateId: "UAT",
|
|
1106
|
+
gateType: "uat",
|
|
1107
|
+
unitType: "run-uat",
|
|
1108
|
+
unitId: `run-uat:${params.milestoneId}/${params.sliceId}`,
|
|
1109
|
+
milestoneId: params.milestoneId,
|
|
1110
|
+
sliceId: params.sliceId,
|
|
1111
|
+
outcome: params.verdict === "PASS" ? "pass" : "fail",
|
|
1112
|
+
failureClass: params.verdict === "PASS" ? "none" : "verification",
|
|
1113
|
+
rationale,
|
|
1114
|
+
findings: assessment,
|
|
1115
|
+
attempt,
|
|
1116
|
+
maxAttempts: attempt,
|
|
1117
|
+
retryable: params.verdict !== "PASS",
|
|
1118
|
+
evaluatedAt,
|
|
1119
|
+
});
|
|
1120
|
+
invalidateStateCache();
|
|
1121
|
+
return {
|
|
1122
|
+
content: [{ type: "text", text: `UAT result saved for ${params.milestoneId}/${params.sliceId}: ${params.verdict}` }],
|
|
1123
|
+
details: {
|
|
1124
|
+
operation: "save_uat_result",
|
|
1125
|
+
milestoneId: params.milestoneId,
|
|
1126
|
+
sliceId: params.sliceId,
|
|
1127
|
+
verdict: params.verdict,
|
|
1128
|
+
gateVerdict,
|
|
1129
|
+
attempt,
|
|
1130
|
+
attemptPath,
|
|
1131
|
+
recommendedNextUnit: params.verdict === "PASS" ? null : "reactive-execute",
|
|
1132
|
+
},
|
|
1133
|
+
};
|
|
1134
|
+
}
|
|
1135
|
+
catch (err) {
|
|
1136
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
1137
|
+
logError("tool", `gsd_uat_result_save failed: ${msg}`, { tool: "gsd_uat_result_save", error: String(err) });
|
|
1138
|
+
return errorResult("save_uat_result", `saving UAT result failed: ${msg}`, msg);
|
|
1139
|
+
}
|
|
1140
|
+
}
|
|
778
1141
|
export async function executePlanMilestone(params, basePath = process.cwd()) {
|
|
779
1142
|
const dbAvailable = await ensureDbOpen(basePath);
|
|
780
1143
|
if (!dbAvailable) {
|
|
@@ -83,6 +83,10 @@ const COMMON_BUDGET_SMALL = 250_000; // ~65K tokens
|
|
|
83
83
|
const TOOLS_ALL = { mode: "all" };
|
|
84
84
|
const TOOLS_PLANNING = { mode: "planning" };
|
|
85
85
|
const TOOLS_VERIFICATION = { mode: "verification" };
|
|
86
|
+
const TOOLS_VERIFICATION_DISPATCH_UAT = {
|
|
87
|
+
mode: "verification",
|
|
88
|
+
allowedSubagents: ["mnemo", "scout", "reviewer", "tester"],
|
|
89
|
+
};
|
|
86
90
|
// Like TOOLS_PLANNING but permits dispatch to read-only recon/planning
|
|
87
91
|
// specialists. Runtime-enforced by write-gate.ts before the subagent tool runs.
|
|
88
92
|
const TOOLS_PLANNING_DISPATCH_RECON = {
|
|
@@ -372,7 +376,7 @@ export const UNIT_MANIFESTS = {
|
|
|
372
376
|
codebaseMap: false,
|
|
373
377
|
preferences: "active-only",
|
|
374
378
|
contextMode: "verification",
|
|
375
|
-
tools:
|
|
379
|
+
tools: TOOLS_VERIFICATION_DISPATCH_UAT,
|
|
376
380
|
artifacts: {
|
|
377
381
|
inline: ["slice-uat"],
|
|
378
382
|
excerpt: ["slice-summary"],
|
|
@@ -551,9 +555,10 @@ export function compileSubagentPermissionContract(policy) {
|
|
|
551
555
|
if (policy.mode === "all") {
|
|
552
556
|
return { allowed: true, allowedSubagents: ["*"], toolsMode: policy.mode };
|
|
553
557
|
}
|
|
554
|
-
if (policy.mode === "planning-dispatch")
|
|
558
|
+
if ((policy.mode === "planning-dispatch" || policy.mode === "verification") &&
|
|
559
|
+
Array.isArray(policy.allowedSubagents)) {
|
|
555
560
|
return {
|
|
556
|
-
allowed:
|
|
561
|
+
allowed: policy.allowedSubagents.length > 0,
|
|
557
562
|
allowedSubagents: [...policy.allowedSubagents],
|
|
558
563
|
toolsMode: policy.mode,
|
|
559
564
|
};
|
|
@@ -8,6 +8,8 @@ import { deriveState } from "./state.js";
|
|
|
8
8
|
import { detectWorktreeName } from "./worktree.js";
|
|
9
9
|
const VALIDATION_BLOCK_RE = /milestone validation returned needs-(?:attention|remediation)|validation verdict is needs-(?:attention|remediation)/i;
|
|
10
10
|
const VALIDATION_SAFE_DISPATCH_COMMANDS = new Set([
|
|
11
|
+
"reassess",
|
|
12
|
+
"reassess-roadmap",
|
|
11
13
|
"validate",
|
|
12
14
|
"validate-milestone",
|
|
13
15
|
]);
|
|
@@ -44,7 +44,7 @@ export function prepareWorkflowMcpForProject(ctx, projectRoot, modelOverride) {
|
|
|
44
44
|
try {
|
|
45
45
|
const result = ensureProjectWorkflowMcpConfig(projectRoot);
|
|
46
46
|
if (result.status !== "unchanged") {
|
|
47
|
-
prepCtx.ui?.notify?.(`
|
|
47
|
+
prepCtx.ui?.notify?.(`GSD MCP Server Prepared at ${result.configPath}`, "info");
|
|
48
48
|
}
|
|
49
49
|
return result;
|
|
50
50
|
}
|
|
@@ -2,6 +2,7 @@ import { execSync } from "node:child_process";
|
|
|
2
2
|
import { existsSync, realpathSync } from "node:fs";
|
|
3
3
|
import { dirname, resolve, sep } from "node:path";
|
|
4
4
|
import { fileURLToPath, pathToFileURL } from "node:url";
|
|
5
|
+
import { RUN_UAT_WORKFLOW_TOOL_NAMES } from "./tool-presentation-plan.js";
|
|
5
6
|
/** Session cwd may be a milestone worktree; MCP config and server discovery use the project root. */
|
|
6
7
|
export function resolveWorkflowMcpProjectRoot(sessionCwd) {
|
|
7
8
|
let resolved;
|
|
@@ -77,6 +78,8 @@ const MCP_WORKFLOW_TOOL_SURFACE = new Set([
|
|
|
77
78
|
"gsd_task_complete",
|
|
78
79
|
"gsd_task_reopen",
|
|
79
80
|
"gsd_update_requirement",
|
|
81
|
+
"gsd_uat_exec",
|
|
82
|
+
"gsd_uat_result_save",
|
|
80
83
|
"gsd_validate_milestone",
|
|
81
84
|
]);
|
|
82
85
|
/** Workflow MCP tools are validated by transport compatibility, not pi tool-compat profiles. */
|
|
@@ -397,8 +400,9 @@ export function getRequiredWorkflowToolsForAutoUnit(unitType) {
|
|
|
397
400
|
];
|
|
398
401
|
case "research-milestone":
|
|
399
402
|
case "research-slice":
|
|
400
|
-
case "run-uat":
|
|
401
403
|
return ["gsd_summary_save"];
|
|
404
|
+
case "run-uat":
|
|
405
|
+
return [...RUN_UAT_WORKFLOW_TOOL_NAMES];
|
|
402
406
|
case "plan-milestone":
|
|
403
407
|
return ["gsd_plan_milestone"];
|
|
404
408
|
case "plan-slice":
|
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
eRWf-RI9bzbrwEurm_3uI
|
|
@@ -5,15 +5,16 @@
|
|
|
5
5
|
"/api/bridge-terminal/input/route": "/api/bridge-terminal/input",
|
|
6
6
|
"/api/bridge-terminal/resize/route": "/api/bridge-terminal/resize",
|
|
7
7
|
"/api/bridge-terminal/stream/route": "/api/bridge-terminal/stream",
|
|
8
|
+
"/api/browse-directories/route": "/api/browse-directories",
|
|
8
9
|
"/api/cleanup/route": "/api/cleanup",
|
|
9
10
|
"/api/dev-mode/route": "/api/dev-mode",
|
|
10
11
|
"/api/captures/route": "/api/captures",
|
|
11
12
|
"/api/doctor/route": "/api/doctor",
|
|
12
|
-
"/api/browse-directories/route": "/api/browse-directories",
|
|
13
13
|
"/api/export-data/route": "/api/export-data",
|
|
14
14
|
"/api/experimental/route": "/api/experimental",
|
|
15
15
|
"/api/forensics/route": "/api/forensics",
|
|
16
16
|
"/api/git/route": "/api/git",
|
|
17
|
+
"/api/files/route": "/api/files",
|
|
17
18
|
"/api/history/route": "/api/history",
|
|
18
19
|
"/api/hooks/route": "/api/hooks",
|
|
19
20
|
"/api/inspect/route": "/api/inspect",
|
|
@@ -21,7 +22,6 @@
|
|
|
21
22
|
"/api/live-state/route": "/api/live-state",
|
|
22
23
|
"/api/mcp-connections/route": "/api/mcp-connections",
|
|
23
24
|
"/api/notifications/route": "/api/notifications",
|
|
24
|
-
"/api/files/route": "/api/files",
|
|
25
25
|
"/api/onboarding/route": "/api/onboarding",
|
|
26
26
|
"/api/preferences/route": "/api/preferences",
|
|
27
27
|
"/api/recovery/route": "/api/recovery",
|
|
@@ -29,20 +29,20 @@
|
|
|
29
29
|
"/api/session/browser/route": "/api/session/browser",
|
|
30
30
|
"/api/session/command/route": "/api/session/command",
|
|
31
31
|
"/api/session/events/route": "/api/session/events",
|
|
32
|
-
"/api/
|
|
32
|
+
"/api/remote-questions/route": "/api/remote-questions",
|
|
33
33
|
"/api/settings-data/route": "/api/settings-data",
|
|
34
|
+
"/api/session/manage/route": "/api/session/manage",
|
|
34
35
|
"/api/shutdown/route": "/api/shutdown",
|
|
35
36
|
"/api/skill-health/route": "/api/skill-health",
|
|
36
37
|
"/api/steer/route": "/api/steer",
|
|
37
|
-
"/api/remote-questions/route": "/api/remote-questions",
|
|
38
38
|
"/api/terminal/input/route": "/api/terminal/input",
|
|
39
39
|
"/api/switch-root/route": "/api/switch-root",
|
|
40
40
|
"/api/terminal/resize/route": "/api/terminal/resize",
|
|
41
41
|
"/api/terminal/sessions/route": "/api/terminal/sessions",
|
|
42
42
|
"/api/terminal/stream/route": "/api/terminal/stream",
|
|
43
|
-
"/api/terminal/upload/route": "/api/terminal/upload",
|
|
44
43
|
"/api/undo/route": "/api/undo",
|
|
45
|
-
"/api/
|
|
44
|
+
"/api/terminal/upload/route": "/api/terminal/upload",
|
|
46
45
|
"/api/visualizer/route": "/api/visualizer",
|
|
46
|
+
"/api/update/route": "/api/update",
|
|
47
47
|
"/page": "/"
|
|
48
48
|
}
|
|
@@ -4,8 +4,8 @@
|
|
|
4
4
|
],
|
|
5
5
|
"devFiles": [],
|
|
6
6
|
"lowPriorityFiles": [
|
|
7
|
-
"static/
|
|
8
|
-
"static/
|
|
7
|
+
"static/eRWf-RI9bzbrwEurm_3uI/_buildManifest.js",
|
|
8
|
+
"static/eRWf-RI9bzbrwEurm_3uI/_ssgManifest.js"
|
|
9
9
|
],
|
|
10
10
|
"rootMainFiles": [
|
|
11
11
|
"static/chunks/webpack-dda80a1ef5587410.js",
|
|
@@ -78,8 +78,8 @@
|
|
|
78
78
|
"dynamicRoutes": {},
|
|
79
79
|
"notFoundRoutes": [],
|
|
80
80
|
"preview": {
|
|
81
|
-
"previewModeId": "
|
|
82
|
-
"previewModeSigningKey": "
|
|
83
|
-
"previewModeEncryptionKey": "
|
|
81
|
+
"previewModeId": "a55c1eb8318320d04a0442fa74665e4e",
|
|
82
|
+
"previewModeSigningKey": "07470565fa87ddad87c0d70f494ae370acebe434edf2a54b651ef62d07766d6d",
|
|
83
|
+
"previewModeEncryptionKey": "ad56ef582670523d7d525d702654f630044870e486022e4478b73527455aa10d"
|
|
84
84
|
}
|
|
85
85
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
<!DOCTYPE html><html id="__next_error__"><head><meta charSet="utf-8"/><meta name="viewport" content="width=device-width, initial-scale=1"/><link rel="preload" as="script" fetchPriority="low" href="/_next/static/chunks/webpack-dda80a1ef5587410.js"/><script src="/_next/static/chunks/51aff721-df603e9695992f6b.js" async=""></script><script src="/_next/static/chunks/686-9424f271d9ce5d07.js" async=""></script><script src="/_next/static/chunks/main-app-90d1d8d5e5d2dc6b.js" async=""></script><title>500: This page couldn’t load</title><style>:root {--next-error-bg: #fff;--next-error-text: #171717;--next-error-title: #171717;--next-error-message: #171717;--next-error-digest: #666666;--next-error-btn-text: #fff;--next-error-btn-bg: #171717;--next-error-btn-border: none;--next-error-btn-secondary-text: #171717;--next-error-btn-secondary-bg: transparent;--next-error-btn-secondary-border: 1px solid rgba(0,0,0,0.08);}@media (prefers-color-scheme: dark) {:root {--next-error-bg: #0a0a0a;--next-error-text: #ededed;--next-error-title: #ededed;--next-error-message: #ededed;--next-error-digest: #a0a0a0;--next-error-btn-text: #0a0a0a;--next-error-btn-bg: #ededed;--next-error-btn-border: none;--next-error-btn-secondary-text: #ededed;--next-error-btn-secondary-bg: transparent;--next-error-btn-secondary-border: 1px solid rgba(255,255,255,0.14);}}body { margin: 0; color: var(--next-error-text); background: var(--next-error-bg); }</style><script src="/_next/static/chunks/polyfills-42372ed130431b0a.js" noModule=""></script></head><body><div hidden=""><!--$--><!--/$--></div><div style="font-family:system-ui,"Segoe UI",Roboto,Helvetica,Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji";height:100vh;display:flex;align-items:center;justify-content:center"><div style="margin-top:-32px;max-width:325px;padding:32px 28px;text-align:left"><svg width="32" height="32" viewBox="-0.2 -1.5 32 32" fill="none" style="margin-bottom:24px"><path d="M16.9328 0C18.0839 0.000116771 19.1334 0.658832 19.634 1.69531L31.4299 26.1309C32.0708 27.4588 31.1036 28.9999 29.6291 29H2.00215C0.527541 29 -0.439628 27.4588 0.201371 26.1309L11.9973 1.69531C12.4979 0.658823 13.5474 7.75066e-05 14.6984 0H16.9328ZM3.59493 26H28.0363L16.9328 3H14.6984L3.59493 26ZM15.8156 19C16.9202 19.0001 17.8156 19.8955 17.8156 21C17.8156 22.1045 16.9202 22.9999 15.8156 23C14.7111 23 13.8156 22.1046 13.8156 21C13.8156 19.8954 14.7111 19 15.8156 19ZM17.3156 16.5H14.3156V8.5H17.3156V16.5Z" fill="var(--next-error-title)"></path></svg><h1 style="font-size:24px;font-weight:500;letter-spacing:-0.02em;line-height:32px;margin:0 0 12px 0;color:var(--next-error-title)">This page couldn’t load</h1><p style="font-size:14px;font-weight:400;line-height:21px;margin:0 0 20px 0;color:var(--next-error-message)">A server error occurred. Reload to try again.</p><form style="margin:0"><button type="submit" style="display:inline-flex;align-items:center;justify-content:center;height:32px;padding:0 12px;font-size:14px;font-weight:500;line-height:20px;border-radius:6px;cursor:pointer;color:var(--next-error-btn-text);background:var(--next-error-btn-bg);border:var(--next-error-btn-border)">Reload</button></form></div></div><!--$--><!--/$--><script src="/_next/static/chunks/webpack-dda80a1ef5587410.js" id="_R_" async=""></script><script>(self.__next_f=self.__next_f||[]).push([0])</script><script>self.__next_f.push([1,"1:\"$Sreact.fragment\"\n2:I[25020,[],\"\"]\n3:I[81130,[],\"\"]\n4:I[84649,[],\"OutletBoundary\"]\n5:\"$Sreact.suspense\"\n8:I[84649,[],\"ViewportBoundary\"]\na:I[84649,[],\"MetadataBoundary\"]\nc:I[45336,[],\"default\",1]\n"])</script><script>self.__next_f.push([1,"0:{\"P\":null,\"c\":[\"\",\"_global-error\"],\"q\":\"\",\"i\":false,\"f\":[[[\"\",{\"children\":[\"_global-error\",{\"children\":[\"__PAGE__\",{}]}]}],[[\"$\",\"$1\",\"c\",{\"children\":[null,[\"$\",\"$L2\",null,{\"parallelRouterKey\":\"children\",\"error\":\"$undefined\",\"errorStyles\":\"$undefined\",\"errorScripts\":\"$undefined\",\"template\":[\"$\",\"$L3\",null,{}],\"templateStyles\":\"$undefined\",\"templateScripts\":\"$undefined\",\"notFound\":\"$undefined\",\"forbidden\":\"$undefined\",\"unauthorized\":\"$undefined\"}]]}],{\"children\":[[\"$\",\"$1\",\"c\",{\"children\":[null,[\"$\",\"$L2\",null,{\"parallelRouterKey\":\"children\",\"error\":\"$undefined\",\"errorStyles\":\"$undefined\",\"errorScripts\":\"$undefined\",\"template\":[\"$\",\"$L3\",null,{}],\"templateStyles\":\"$undefined\",\"templateScripts\":\"$undefined\",\"notFound\":\"$undefined\",\"forbidden\":\"$undefined\",\"unauthorized\":\"$undefined\"}]]}],{\"children\":[[\"$\",\"$1\",\"c\",{\"children\":[[\"$\",\"html\",null,{\"id\":\"__next_error__\",\"children\":[[\"$\",\"head\",null,{\"children\":[[\"$\",\"title\",null,{\"children\":\"500: This page couldn’t load\"}],[\"$\",\"style\",null,{\"dangerouslySetInnerHTML\":{\"__html\":\":root {--next-error-bg: #fff;--next-error-text: #171717;--next-error-title: #171717;--next-error-message: #171717;--next-error-digest: #666666;--next-error-btn-text: #fff;--next-error-btn-bg: #171717;--next-error-btn-border: none;--next-error-btn-secondary-text: #171717;--next-error-btn-secondary-bg: transparent;--next-error-btn-secondary-border: 1px solid rgba(0,0,0,0.08);}@media (prefers-color-scheme: dark) {:root {--next-error-bg: #0a0a0a;--next-error-text: #ededed;--next-error-title: #ededed;--next-error-message: #ededed;--next-error-digest: #a0a0a0;--next-error-btn-text: #0a0a0a;--next-error-btn-bg: #ededed;--next-error-btn-border: none;--next-error-btn-secondary-text: #ededed;--next-error-btn-secondary-bg: transparent;--next-error-btn-secondary-border: 1px solid rgba(255,255,255,0.14);}}body { margin: 0; color: var(--next-error-text); background: var(--next-error-bg); }\"}}]]}],[\"$\",\"body\",null,{\"children\":[\"$\",\"div\",null,{\"style\":{\"fontFamily\":\"system-ui,\\\"Segoe UI\\\",Roboto,Helvetica,Arial,sans-serif,\\\"Apple Color Emoji\\\",\\\"Segoe UI Emoji\\\"\",\"height\":\"100vh\",\"display\":\"flex\",\"alignItems\":\"center\",\"justifyContent\":\"center\"},\"children\":[\"$\",\"div\",null,{\"style\":{\"marginTop\":\"-32px\",\"maxWidth\":\"325px\",\"padding\":\"32px 28px\",\"textAlign\":\"left\"},\"children\":[[\"$\",\"svg\",null,{\"width\":\"32\",\"height\":\"32\",\"viewBox\":\"-0.2 -1.5 32 32\",\"fill\":\"none\",\"style\":{\"marginBottom\":\"24px\"},\"children\":[\"$\",\"path\",null,{\"d\":\"M16.9328 0C18.0839 0.000116771 19.1334 0.658832 19.634 1.69531L31.4299 26.1309C32.0708 27.4588 31.1036 28.9999 29.6291 29H2.00215C0.527541 29 -0.439628 27.4588 0.201371 26.1309L11.9973 1.69531C12.4979 0.658823 13.5474 7.75066e-05 14.6984 0H16.9328ZM3.59493 26H28.0363L16.9328 3H14.6984L3.59493 26ZM15.8156 19C16.9202 19.0001 17.8156 19.8955 17.8156 21C17.8156 22.1045 16.9202 22.9999 15.8156 23C14.7111 23 13.8156 22.1046 13.8156 21C13.8156 19.8954 14.7111 19 15.8156 19ZM17.3156 16.5H14.3156V8.5H17.3156V16.5Z\",\"fill\":\"var(--next-error-title)\"}]}],[\"$\",\"h1\",null,{\"style\":{\"fontSize\":\"24px\",\"fontWeight\":500,\"letterSpacing\":\"-0.02em\",\"lineHeight\":\"32px\",\"margin\":\"0 0 12px 0\",\"color\":\"var(--next-error-title)\"},\"children\":\"This page couldn’t load\"}],[\"$\",\"p\",null,{\"style\":{\"fontSize\":\"14px\",\"fontWeight\":400,\"lineHeight\":\"21px\",\"margin\":\"0 0 20px 0\",\"color\":\"var(--next-error-message)\"},\"children\":\"A server error occurred. Reload to try again.\"}],[\"$\",\"form\",null,{\"style\":{\"margin\":0},\"children\":[\"$\",\"button\",null,{\"type\":\"submit\",\"style\":{\"display\":\"inline-flex\",\"alignItems\":\"center\",\"justifyContent\":\"center\",\"height\":\"32px\",\"padding\":\"0 12px\",\"fontSize\":\"14px\",\"fontWeight\":500,\"lineHeight\":\"20px\",\"borderRadius\":\"6px\",\"cursor\":\"pointer\",\"color\":\"var(--next-error-btn-text)\",\"background\":\"var(--next-error-btn-bg)\",\"border\":\"var(--next-error-btn-border)\"},\"children\":\"Reload\"}]}]]}]}]}]]}],null,[\"$\",\"$L4\",null,{\"children\":[\"$\",\"$5\",null,{\"name\":\"Next.MetadataOutlet\",\"children\":\"$@6\"}]}]]}],{},null,false,null]},null,false,\"$@7\"]},null,false,\"$@7\"],[\"$\",\"$1\",\"h\",{\"children\":[null,[\"$\",\"$L8\",null,{\"children\":\"$L9\"}],[\"$\",\"div\",null,{\"hidden\":true,\"children\":[\"$\",\"$La\",null,{\"children\":[\"$\",\"$5\",null,{\"name\":\"Next.Metadata\",\"children\":\"$Lb\"}]}]}],null]}],false]],\"m\":\"$undefined\",\"G\":[\"$c\",[]],\"S\":true,\"h\":null,\"s\":\"$undefined\",\"l\":\"$undefined\",\"p\":\"$undefined\",\"d\":\"$undefined\",\"b\":\"
|
|
1
|
+
<!DOCTYPE html><html id="__next_error__"><head><meta charSet="utf-8"/><meta name="viewport" content="width=device-width, initial-scale=1"/><link rel="preload" as="script" fetchPriority="low" href="/_next/static/chunks/webpack-dda80a1ef5587410.js"/><script src="/_next/static/chunks/51aff721-df603e9695992f6b.js" async=""></script><script src="/_next/static/chunks/686-9424f271d9ce5d07.js" async=""></script><script src="/_next/static/chunks/main-app-90d1d8d5e5d2dc6b.js" async=""></script><title>500: This page couldn’t load</title><style>:root {--next-error-bg: #fff;--next-error-text: #171717;--next-error-title: #171717;--next-error-message: #171717;--next-error-digest: #666666;--next-error-btn-text: #fff;--next-error-btn-bg: #171717;--next-error-btn-border: none;--next-error-btn-secondary-text: #171717;--next-error-btn-secondary-bg: transparent;--next-error-btn-secondary-border: 1px solid rgba(0,0,0,0.08);}@media (prefers-color-scheme: dark) {:root {--next-error-bg: #0a0a0a;--next-error-text: #ededed;--next-error-title: #ededed;--next-error-message: #ededed;--next-error-digest: #a0a0a0;--next-error-btn-text: #0a0a0a;--next-error-btn-bg: #ededed;--next-error-btn-border: none;--next-error-btn-secondary-text: #ededed;--next-error-btn-secondary-bg: transparent;--next-error-btn-secondary-border: 1px solid rgba(255,255,255,0.14);}}body { margin: 0; color: var(--next-error-text); background: var(--next-error-bg); }</style><script src="/_next/static/chunks/polyfills-42372ed130431b0a.js" noModule=""></script></head><body><div hidden=""><!--$--><!--/$--></div><div style="font-family:system-ui,"Segoe UI",Roboto,Helvetica,Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji";height:100vh;display:flex;align-items:center;justify-content:center"><div style="margin-top:-32px;max-width:325px;padding:32px 28px;text-align:left"><svg width="32" height="32" viewBox="-0.2 -1.5 32 32" fill="none" style="margin-bottom:24px"><path d="M16.9328 0C18.0839 0.000116771 19.1334 0.658832 19.634 1.69531L31.4299 26.1309C32.0708 27.4588 31.1036 28.9999 29.6291 29H2.00215C0.527541 29 -0.439628 27.4588 0.201371 26.1309L11.9973 1.69531C12.4979 0.658823 13.5474 7.75066e-05 14.6984 0H16.9328ZM3.59493 26H28.0363L16.9328 3H14.6984L3.59493 26ZM15.8156 19C16.9202 19.0001 17.8156 19.8955 17.8156 21C17.8156 22.1045 16.9202 22.9999 15.8156 23C14.7111 23 13.8156 22.1046 13.8156 21C13.8156 19.8954 14.7111 19 15.8156 19ZM17.3156 16.5H14.3156V8.5H17.3156V16.5Z" fill="var(--next-error-title)"></path></svg><h1 style="font-size:24px;font-weight:500;letter-spacing:-0.02em;line-height:32px;margin:0 0 12px 0;color:var(--next-error-title)">This page couldn’t load</h1><p style="font-size:14px;font-weight:400;line-height:21px;margin:0 0 20px 0;color:var(--next-error-message)">A server error occurred. Reload to try again.</p><form style="margin:0"><button type="submit" style="display:inline-flex;align-items:center;justify-content:center;height:32px;padding:0 12px;font-size:14px;font-weight:500;line-height:20px;border-radius:6px;cursor:pointer;color:var(--next-error-btn-text);background:var(--next-error-btn-bg);border:var(--next-error-btn-border)">Reload</button></form></div></div><!--$--><!--/$--><script src="/_next/static/chunks/webpack-dda80a1ef5587410.js" id="_R_" async=""></script><script>(self.__next_f=self.__next_f||[]).push([0])</script><script>self.__next_f.push([1,"1:\"$Sreact.fragment\"\n2:I[25020,[],\"\"]\n3:I[81130,[],\"\"]\n4:I[84649,[],\"OutletBoundary\"]\n5:\"$Sreact.suspense\"\n8:I[84649,[],\"ViewportBoundary\"]\na:I[84649,[],\"MetadataBoundary\"]\nc:I[45336,[],\"default\",1]\n"])</script><script>self.__next_f.push([1,"0:{\"P\":null,\"c\":[\"\",\"_global-error\"],\"q\":\"\",\"i\":false,\"f\":[[[\"\",{\"children\":[\"_global-error\",{\"children\":[\"__PAGE__\",{}]}]}],[[\"$\",\"$1\",\"c\",{\"children\":[null,[\"$\",\"$L2\",null,{\"parallelRouterKey\":\"children\",\"error\":\"$undefined\",\"errorStyles\":\"$undefined\",\"errorScripts\":\"$undefined\",\"template\":[\"$\",\"$L3\",null,{}],\"templateStyles\":\"$undefined\",\"templateScripts\":\"$undefined\",\"notFound\":\"$undefined\",\"forbidden\":\"$undefined\",\"unauthorized\":\"$undefined\"}]]}],{\"children\":[[\"$\",\"$1\",\"c\",{\"children\":[null,[\"$\",\"$L2\",null,{\"parallelRouterKey\":\"children\",\"error\":\"$undefined\",\"errorStyles\":\"$undefined\",\"errorScripts\":\"$undefined\",\"template\":[\"$\",\"$L3\",null,{}],\"templateStyles\":\"$undefined\",\"templateScripts\":\"$undefined\",\"notFound\":\"$undefined\",\"forbidden\":\"$undefined\",\"unauthorized\":\"$undefined\"}]]}],{\"children\":[[\"$\",\"$1\",\"c\",{\"children\":[[\"$\",\"html\",null,{\"id\":\"__next_error__\",\"children\":[[\"$\",\"head\",null,{\"children\":[[\"$\",\"title\",null,{\"children\":\"500: This page couldn’t load\"}],[\"$\",\"style\",null,{\"dangerouslySetInnerHTML\":{\"__html\":\":root {--next-error-bg: #fff;--next-error-text: #171717;--next-error-title: #171717;--next-error-message: #171717;--next-error-digest: #666666;--next-error-btn-text: #fff;--next-error-btn-bg: #171717;--next-error-btn-border: none;--next-error-btn-secondary-text: #171717;--next-error-btn-secondary-bg: transparent;--next-error-btn-secondary-border: 1px solid rgba(0,0,0,0.08);}@media (prefers-color-scheme: dark) {:root {--next-error-bg: #0a0a0a;--next-error-text: #ededed;--next-error-title: #ededed;--next-error-message: #ededed;--next-error-digest: #a0a0a0;--next-error-btn-text: #0a0a0a;--next-error-btn-bg: #ededed;--next-error-btn-border: none;--next-error-btn-secondary-text: #ededed;--next-error-btn-secondary-bg: transparent;--next-error-btn-secondary-border: 1px solid rgba(255,255,255,0.14);}}body { margin: 0; color: var(--next-error-text); background: var(--next-error-bg); }\"}}]]}],[\"$\",\"body\",null,{\"children\":[\"$\",\"div\",null,{\"style\":{\"fontFamily\":\"system-ui,\\\"Segoe UI\\\",Roboto,Helvetica,Arial,sans-serif,\\\"Apple Color Emoji\\\",\\\"Segoe UI Emoji\\\"\",\"height\":\"100vh\",\"display\":\"flex\",\"alignItems\":\"center\",\"justifyContent\":\"center\"},\"children\":[\"$\",\"div\",null,{\"style\":{\"marginTop\":\"-32px\",\"maxWidth\":\"325px\",\"padding\":\"32px 28px\",\"textAlign\":\"left\"},\"children\":[[\"$\",\"svg\",null,{\"width\":\"32\",\"height\":\"32\",\"viewBox\":\"-0.2 -1.5 32 32\",\"fill\":\"none\",\"style\":{\"marginBottom\":\"24px\"},\"children\":[\"$\",\"path\",null,{\"d\":\"M16.9328 0C18.0839 0.000116771 19.1334 0.658832 19.634 1.69531L31.4299 26.1309C32.0708 27.4588 31.1036 28.9999 29.6291 29H2.00215C0.527541 29 -0.439628 27.4588 0.201371 26.1309L11.9973 1.69531C12.4979 0.658823 13.5474 7.75066e-05 14.6984 0H16.9328ZM3.59493 26H28.0363L16.9328 3H14.6984L3.59493 26ZM15.8156 19C16.9202 19.0001 17.8156 19.8955 17.8156 21C17.8156 22.1045 16.9202 22.9999 15.8156 23C14.7111 23 13.8156 22.1046 13.8156 21C13.8156 19.8954 14.7111 19 15.8156 19ZM17.3156 16.5H14.3156V8.5H17.3156V16.5Z\",\"fill\":\"var(--next-error-title)\"}]}],[\"$\",\"h1\",null,{\"style\":{\"fontSize\":\"24px\",\"fontWeight\":500,\"letterSpacing\":\"-0.02em\",\"lineHeight\":\"32px\",\"margin\":\"0 0 12px 0\",\"color\":\"var(--next-error-title)\"},\"children\":\"This page couldn’t load\"}],[\"$\",\"p\",null,{\"style\":{\"fontSize\":\"14px\",\"fontWeight\":400,\"lineHeight\":\"21px\",\"margin\":\"0 0 20px 0\",\"color\":\"var(--next-error-message)\"},\"children\":\"A server error occurred. Reload to try again.\"}],[\"$\",\"form\",null,{\"style\":{\"margin\":0},\"children\":[\"$\",\"button\",null,{\"type\":\"submit\",\"style\":{\"display\":\"inline-flex\",\"alignItems\":\"center\",\"justifyContent\":\"center\",\"height\":\"32px\",\"padding\":\"0 12px\",\"fontSize\":\"14px\",\"fontWeight\":500,\"lineHeight\":\"20px\",\"borderRadius\":\"6px\",\"cursor\":\"pointer\",\"color\":\"var(--next-error-btn-text)\",\"background\":\"var(--next-error-btn-bg)\",\"border\":\"var(--next-error-btn-border)\"},\"children\":\"Reload\"}]}]]}]}]}]]}],null,[\"$\",\"$L4\",null,{\"children\":[\"$\",\"$5\",null,{\"name\":\"Next.MetadataOutlet\",\"children\":\"$@6\"}]}]]}],{},null,false,null]},null,false,\"$@7\"]},null,false,\"$@7\"],[\"$\",\"$1\",\"h\",{\"children\":[null,[\"$\",\"$L8\",null,{\"children\":\"$L9\"}],[\"$\",\"div\",null,{\"hidden\":true,\"children\":[\"$\",\"$La\",null,{\"children\":[\"$\",\"$5\",null,{\"name\":\"Next.Metadata\",\"children\":\"$Lb\"}]}]}],null]}],false]],\"m\":\"$undefined\",\"G\":[\"$c\",[]],\"S\":true,\"h\":null,\"s\":\"$undefined\",\"l\":\"$undefined\",\"p\":\"$undefined\",\"d\":\"$undefined\",\"b\":\"eRWf-RI9bzbrwEurm_3uI\"}\n"])</script><script>self.__next_f.push([1,"d:[]\n7:\"$Wd\"\n"])</script><script>self.__next_f.push([1,"9:[[\"$\",\"meta\",\"0\",{\"charSet\":\"utf-8\"}],[\"$\",\"meta\",\"1\",{\"name\":\"viewport\",\"content\":\"width=device-width, initial-scale=1\"}]]\n"])</script><script>self.__next_f.push([1,"6:null\nb:[]\n"])</script></body></html>
|