@opengsd/gsd-pi 1.1.1-dev.9bb7453 → 1.1.1-dev.9f86580
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/browser-tools/engine/managed-gsd-browser.js +18 -2
- package/dist/resources/extensions/browser-tools/engine/selection.js +1 -1
- package/dist/resources/extensions/browser-tools/extension-manifest.json +1 -1
- package/dist/resources/extensions/browser-tools/index.js +29 -2
- package/dist/resources/extensions/browser-tools/web-app-detect.js +52 -0
- package/dist/resources/extensions/gsd/auto/phases.js +45 -3
- package/dist/resources/extensions/gsd/auto/session.js +2 -0
- package/dist/resources/extensions/gsd/auto-dispatch.js +21 -2
- package/dist/resources/extensions/gsd/auto-model-selection.js +26 -0
- package/dist/resources/extensions/gsd/auto-prompts.js +4 -0
- package/dist/resources/extensions/gsd/auto-recovery.js +3 -4
- package/dist/resources/extensions/gsd/auto-timers.js +24 -10
- package/dist/resources/extensions/gsd/auto-unit-tool-scope.js +18 -66
- package/dist/resources/extensions/gsd/auto-worktree.js +18 -5
- package/dist/resources/extensions/gsd/auto.js +26 -4
- package/dist/resources/extensions/gsd/bootstrap/db-tools.js +16 -10
- package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +48 -29
- package/dist/resources/extensions/gsd/bootstrap/system-context.js +1 -1
- package/dist/resources/extensions/gsd/bootstrap/write-gate.js +18 -29
- package/dist/resources/extensions/gsd/closeout-consistency-gate.js +61 -0
- package/dist/resources/extensions/gsd/commands/handlers/auto.js +10 -0
- package/dist/resources/extensions/gsd/commands-mcp-status.js +1 -1
- package/dist/resources/extensions/gsd/config-overlay.js +1 -0
- package/dist/resources/extensions/gsd/context-masker.js +129 -5
- package/dist/resources/extensions/gsd/guided-flow.js +93 -108
- package/dist/resources/extensions/gsd/milestone-closeout.js +3 -1
- package/dist/resources/extensions/gsd/pending-auto-start.js +0 -1
- package/dist/resources/extensions/gsd/planner-handoff.js +98 -0
- package/dist/resources/extensions/gsd/preferences-models.js +1 -0
- package/dist/resources/extensions/gsd/prompts/plan-milestone.md +1 -1
- package/dist/resources/extensions/gsd/prompts/run-uat.md +5 -19
- package/dist/resources/extensions/gsd/prompts/system.md +1 -1
- package/dist/resources/extensions/gsd/recovery-classification.js +20 -0
- package/dist/resources/extensions/gsd/skill-manifest.js +12 -0
- package/dist/resources/extensions/gsd/tool-contract.js +6 -1
- package/dist/resources/extensions/gsd/tool-presentation-plan.js +47 -7
- package/dist/resources/extensions/gsd/tools/complete-slice.js +28 -1
- package/dist/resources/extensions/gsd/tools/workflow-tool-executors.js +113 -8
- package/dist/resources/extensions/gsd/unit-tool-contracts.js +193 -0
- package/dist/resources/extensions/gsd/workflow-mcp.js +5 -78
- package/dist/resources/extensions/gsd/worktree-manager.js +26 -0
- package/dist/resources/extensions/gsd/worktree-reentry.js +96 -0
- package/dist/resources/extensions/shared/gsd-browser-cli.js +6 -0
- package/dist/web/standalone/.next/BUILD_ID +1 -1
- package/dist/web/standalone/.next/app-path-routes-manifest.json +5 -5
- 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 +5 -5
- 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 +1 -1
- package/packages/cloud-mcp-gateway/package.json +2 -2
- 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/tool-execution.d.ts.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.js +5 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.js.map +1 -1
- package/packages/gsd-agent-modes/package.json +7 -7
- package/packages/mcp-server/package.json +3 -3
- package/packages/native/package.json +1 -1
- package/packages/pi-agent-core/dist/agent-loop.js +4 -3
- package/packages/pi-agent-core/dist/agent-loop.js.map +1 -1
- package/packages/pi-agent-core/dist/harness/agent-harness.d.ts.map +1 -1
- package/packages/pi-agent-core/dist/harness/agent-harness.js +3 -1
- package/packages/pi-agent-core/dist/harness/agent-harness.js.map +1 -1
- package/packages/pi-agent-core/dist/harness/types.d.ts +1 -0
- package/packages/pi-agent-core/dist/harness/types.d.ts.map +1 -1
- package/packages/pi-agent-core/dist/harness/types.js.map +1 -1
- package/packages/pi-agent-core/dist/types.d.ts +3 -1
- package/packages/pi-agent-core/dist/types.d.ts.map +1 -1
- package/packages/pi-agent-core/dist/types.js.map +1 -1
- package/packages/pi-agent-core/package.json +1 -1
- package/packages/pi-ai/dist/models.generated.d.ts +157 -18
- package/packages/pi-ai/dist/models.generated.d.ts.map +1 -1
- package/packages/pi-ai/dist/models.generated.js +159 -36
- package/packages/pi-ai/dist/models.generated.js.map +1 -1
- package/packages/pi-ai/dist/providers/transform-messages.d.ts.map +1 -1
- package/packages/pi-ai/dist/providers/transform-messages.js +8 -1
- package/packages/pi-ai/dist/providers/transform-messages.js.map +1 -1
- package/packages/pi-ai/package.json +1 -1
- package/packages/pi-coding-agent/dist/core/extensions/extension-upstream-types.d.ts +3 -0
- package/packages/pi-coding-agent/dist/core/extensions/extension-upstream-types.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/extensions/extension-upstream-types.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/tools/bash.js +2 -2
- package/packages/pi-coding-agent/dist/core/tools/bash.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/tools/edit.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/tools/edit.js +3 -2
- package/packages/pi-coding-agent/dist/core/tools/edit.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/tools/render-utils.d.ts +1 -0
- package/packages/pi-coding-agent/dist/core/tools/render-utils.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/tools/render-utils.js +6 -0
- package/packages/pi-coding-agent/dist/core/tools/render-utils.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/tools/write.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/tools/write.js +3 -2
- package/packages/pi-coding-agent/dist/core/tools/write.js.map +1 -1
- package/packages/pi-coding-agent/package.json +7 -7
- package/packages/pi-tui/package.json +1 -1
- package/packages/rpc-client/package.json +2 -2
- package/pkg/package.json +1 -1
- package/scripts/install/handoff.js +16 -3
- package/src/resources/extensions/browser-tools/engine/managed-gsd-browser.ts +21 -2
- package/src/resources/extensions/browser-tools/engine/selection.ts +1 -1
- package/src/resources/extensions/browser-tools/extension-manifest.json +1 -1
- package/src/resources/extensions/browser-tools/index.ts +36 -5
- package/src/resources/extensions/browser-tools/tests/browser-engine-selection.test.mjs +2 -2
- package/src/resources/extensions/browser-tools/tests/gsd-browser-launch-config.test.mjs +37 -0
- package/src/resources/extensions/browser-tools/tests/web-app-detect.test.mjs +68 -0
- package/src/resources/extensions/browser-tools/web-app-detect.ts +63 -0
- package/src/resources/extensions/gsd/auto/phases.ts +48 -6
- package/src/resources/extensions/gsd/auto/session.ts +2 -0
- package/src/resources/extensions/gsd/auto-dispatch.ts +48 -2
- package/src/resources/extensions/gsd/auto-model-selection.ts +26 -0
- package/src/resources/extensions/gsd/auto-prompts.ts +4 -0
- package/src/resources/extensions/gsd/auto-recovery.ts +3 -3
- package/src/resources/extensions/gsd/auto-timers.ts +25 -9
- package/src/resources/extensions/gsd/auto-unit-tool-scope.ts +43 -74
- package/src/resources/extensions/gsd/auto-worktree.ts +23 -5
- package/src/resources/extensions/gsd/auto.ts +28 -4
- package/src/resources/extensions/gsd/bootstrap/db-tools.ts +16 -10
- package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +63 -29
- package/src/resources/extensions/gsd/bootstrap/system-context.ts +1 -1
- package/src/resources/extensions/gsd/bootstrap/write-gate.ts +50 -54
- package/src/resources/extensions/gsd/closeout-consistency-gate.ts +137 -0
- package/src/resources/extensions/gsd/commands/handlers/auto.ts +9 -0
- package/src/resources/extensions/gsd/commands-mcp-status.ts +1 -1
- package/src/resources/extensions/gsd/config-overlay.ts +1 -0
- package/src/resources/extensions/gsd/context-masker.ts +152 -5
- package/src/resources/extensions/gsd/guided-flow.ts +128 -135
- package/src/resources/extensions/gsd/milestone-closeout.ts +3 -1
- package/src/resources/extensions/gsd/pending-auto-start.ts +0 -2
- package/src/resources/extensions/gsd/planner-handoff.ts +149 -0
- package/src/resources/extensions/gsd/preferences-models.ts +1 -0
- package/src/resources/extensions/gsd/preferences-types.ts +8 -0
- package/src/resources/extensions/gsd/prompts/plan-milestone.md +1 -1
- package/src/resources/extensions/gsd/prompts/run-uat.md +5 -19
- package/src/resources/extensions/gsd/prompts/system.md +1 -1
- package/src/resources/extensions/gsd/recovery-classification.ts +20 -0
- package/src/resources/extensions/gsd/skill-manifest.ts +12 -0
- package/src/resources/extensions/gsd/tests/auto-loop.test.ts +99 -0
- package/src/resources/extensions/gsd/tests/auto-model-selection-tool-poisoning.test.ts +66 -4
- package/src/resources/extensions/gsd/tests/auto-recovery.test.ts +10 -2
- package/src/resources/extensions/gsd/tests/auto-start-bootstrap-await-3420.test.ts +4 -1
- package/src/resources/extensions/gsd/tests/auto-supervisor.test.mjs +4 -0
- package/src/resources/extensions/gsd/tests/auto-warning-noise-regression.test.ts +12 -2
- package/src/resources/extensions/gsd/tests/bundled-skill-triggers.test.ts +9 -0
- package/src/resources/extensions/gsd/tests/check-auto-start-pending-gate.test.ts +9 -15
- package/src/resources/extensions/gsd/tests/check-auto-start-ready-guard.test.ts +26 -16
- package/src/resources/extensions/gsd/tests/commands-dispatcher-unmerged-milestone.test.ts +21 -0
- package/src/resources/extensions/gsd/tests/complete-slice-verification-gate.test.ts +118 -0
- package/src/resources/extensions/gsd/tests/context-masker.test.ts +56 -1
- package/src/resources/extensions/gsd/tests/custom-engine-loop-integration.test.ts +1 -0
- package/src/resources/extensions/gsd/tests/dispatch-complete-milestone-guard.test.ts +40 -1
- package/src/resources/extensions/gsd/tests/dispatch-rule-coverage.test.ts +24 -0
- package/src/resources/extensions/gsd/tests/gate-1b-orphan-discrimination.test.ts +31 -79
- package/src/resources/extensions/gsd/tests/guided-flow-session-isolation.test.ts +5 -3
- package/src/resources/extensions/gsd/tests/guided-flow-state-rebuild.test.ts +40 -4
- package/src/resources/extensions/gsd/tests/integration/auto-worktree-milestone-merge.test.ts +8 -0
- package/src/resources/extensions/gsd/tests/integration/parallel-merge.test.ts +16 -0
- package/src/resources/extensions/gsd/tests/integration/run-uat.test.ts +7 -1
- package/src/resources/extensions/gsd/tests/interrupted-session-auto.test.ts +27 -0
- package/src/resources/extensions/gsd/tests/journal-integration.test.ts +1 -0
- package/src/resources/extensions/gsd/tests/mcp-project-config.test.ts +7 -1
- package/src/resources/extensions/gsd/tests/mcp-status.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/merge-closeout-consistency-gate.test.ts +63 -0
- package/src/resources/extensions/gsd/tests/merge-db-cycle.test.ts +10 -1
- package/src/resources/extensions/gsd/tests/milestone-closeout.test.ts +9 -1
- package/src/resources/extensions/gsd/tests/planner-handoff.test.ts +100 -0
- package/src/resources/extensions/gsd/tests/prompt-contracts.test.ts +147 -5
- package/src/resources/extensions/gsd/tests/provider-switch-observer.test.ts +55 -0
- package/src/resources/extensions/gsd/tests/register-hooks-depth-verification.test.ts +44 -0
- package/src/resources/extensions/gsd/tests/run-uat-composer.test.ts +4 -0
- package/src/resources/extensions/gsd/tests/runtime-invariant-modules.test.ts +56 -0
- package/src/resources/extensions/gsd/tests/skill-manifest.test.ts +4 -3
- package/src/resources/extensions/gsd/tests/token-tool-gating.test.ts +4 -4
- package/src/resources/extensions/gsd/tests/workflow-mcp.test.ts +77 -10
- package/src/resources/extensions/gsd/tests/workflow-tool-executors.test.ts +409 -0
- package/src/resources/extensions/gsd/tests/worktree-reentry.test.ts +102 -0
- package/src/resources/extensions/gsd/tests/write-gate-planning-unit.test.ts +15 -0
- package/src/resources/extensions/gsd/tool-contract.ts +7 -1
- package/src/resources/extensions/gsd/tool-presentation-plan.ts +82 -7
- package/src/resources/extensions/gsd/tools/complete-slice.ts +29 -1
- package/src/resources/extensions/gsd/tools/workflow-tool-executors.ts +146 -9
- package/src/resources/extensions/gsd/unit-tool-contracts.ts +210 -0
- package/src/resources/extensions/gsd/workflow-mcp.ts +5 -78
- package/src/resources/extensions/gsd/worktree-manager.ts +32 -0
- package/src/resources/extensions/gsd/worktree-reentry.ts +103 -0
- package/src/resources/extensions/shared/gsd-browser-cli.ts +6 -0
- package/src/resources/extensions/gsd/tests/gate-1b-recovery-bound-corrections.test.ts +0 -246
- package/src/resources/extensions/gsd/tests/gate-1b-recovery-bound.test.ts +0 -218
- /package/dist/web/standalone/.next/static/{jBtwT9v1u2lUA3UEOy_ZH → zzYMrKpPGfRQRxSFO32Jr}/_buildManifest.js +0 -0
- /package/dist/web/standalone/.next/static/{jBtwT9v1u2lUA3UEOy_ZH → zzYMrKpPGfRQRxSFO32Jr}/_ssgManifest.js +0 -0
|
@@ -1,59 +1,13 @@
|
|
|
1
1
|
import { parseUnitId } from "./unit-id.js";
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
"browser_click",
|
|
7
|
-
"browser_type",
|
|
8
|
-
"browser_fill_form",
|
|
9
|
-
"browser_click_ref",
|
|
10
|
-
"browser_fill_ref",
|
|
11
|
-
"browser_wait_for",
|
|
12
|
-
"browser_assert",
|
|
13
|
-
"browser_verify",
|
|
14
|
-
"browser_screenshot",
|
|
15
|
-
"browser_snapshot_refs",
|
|
16
|
-
"browser_find",
|
|
17
|
-
"browser_get_console_logs",
|
|
18
|
-
"browser_get_network_logs",
|
|
19
|
-
"browser_evaluate",
|
|
20
|
-
"browser_reload",
|
|
21
|
-
"browser_batch",
|
|
22
|
-
"browser_act",
|
|
23
|
-
] as const;
|
|
2
|
+
import {
|
|
3
|
+
AUTO_UNIT_SCOPED_TOOLS,
|
|
4
|
+
getForbiddenGsdToolReason,
|
|
5
|
+
} from "./unit-tool-contracts.js";
|
|
24
6
|
|
|
25
|
-
export
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
"gsd_summary_save",
|
|
30
|
-
"gsd_decision_save",
|
|
31
|
-
"gsd_requirement_save",
|
|
32
|
-
"gsd_requirement_update",
|
|
33
|
-
"gsd_plan_milestone",
|
|
34
|
-
"gsd_milestone_generate_id",
|
|
35
|
-
],
|
|
36
|
-
"discuss-slice": ["gsd_summary_save", "gsd_decision_save"],
|
|
37
|
-
"validate-milestone": ["gsd_validate_milestone", "gsd_reassess_roadmap", "subagent"],
|
|
38
|
-
"complete-milestone": ["gsd_complete_milestone", "subagent"],
|
|
39
|
-
"research-slice": ["gsd_summary_save", "gsd_decision_save"],
|
|
40
|
-
"plan-slice": ["gsd_plan_slice", "gsd_plan_task", "gsd_decision_save"],
|
|
41
|
-
"refine-slice": ["gsd_plan_slice", "gsd_plan_task", "gsd_decision_save"],
|
|
42
|
-
"replan-slice": ["gsd_replan_slice", "gsd_plan_task", "gsd_decision_save"],
|
|
43
|
-
"complete-slice": ["gsd_slice_complete", "gsd_task_reopen", "gsd_replan_slice", "gsd_decision_save", "gsd_requirement_update", "subagent"],
|
|
44
|
-
"reassess-roadmap": ["gsd_reassess_roadmap"],
|
|
45
|
-
"execute-task": ["gsd_task_complete", "gsd_decision_save"],
|
|
46
|
-
"execute-task-simple": ["gsd_task_complete", "gsd_decision_save"],
|
|
47
|
-
"reactive-execute": ["gsd_task_complete", "gsd_decision_save"],
|
|
48
|
-
"run-uat": [...RUN_UAT_WORKFLOW_TOOL_NAMES, "subagent", ...RUN_UAT_BROWSER_TOOL_NAMES],
|
|
49
|
-
"gate-evaluate": ["gsd_save_gate_result"],
|
|
50
|
-
"rewrite-docs": ["gsd_summary_save", "gsd_decision_save"],
|
|
51
|
-
"workflow-preferences": ["gsd_summary_save"],
|
|
52
|
-
"discuss-project": ["gsd_summary_save", "gsd_decision_save", "gsd_requirement_save"],
|
|
53
|
-
"discuss-requirements": ["gsd_requirement_save", "gsd_summary_save"],
|
|
54
|
-
"research-decision": ["gsd_summary_save"],
|
|
55
|
-
"research-project": ["gsd_summary_save", "gsd_decision_save"],
|
|
56
|
-
};
|
|
7
|
+
export {
|
|
8
|
+
AUTO_UNIT_SCOPED_TOOLS,
|
|
9
|
+
RUN_UAT_BROWSER_TOOL_NAMES,
|
|
10
|
+
} from "./unit-tool-contracts.js";
|
|
57
11
|
|
|
58
12
|
const WORKFLOW_TOOL_ALIASES: Record<string, string> = {
|
|
59
13
|
gsd_save_decision: "gsd_decision_save",
|
|
@@ -97,6 +51,14 @@ const SCOPED_GSD_LIFECYCLE_TOOLS = new Set(
|
|
|
97
51
|
.map(canonicalWorkflowToolName),
|
|
98
52
|
);
|
|
99
53
|
|
|
54
|
+
export const GSD_PHASE_SCOPE_DISPLAY_REASON = "This GSD phase only allows its scoped workflow tools.";
|
|
55
|
+
|
|
56
|
+
type AutoUnitToolScopeResult = {
|
|
57
|
+
block: boolean;
|
|
58
|
+
reason?: string;
|
|
59
|
+
displayReason?: string;
|
|
60
|
+
};
|
|
61
|
+
|
|
100
62
|
function stripMcpToolPrefix(toolName: string): string {
|
|
101
63
|
if (!toolName.startsWith("mcp__")) return toolName;
|
|
102
64
|
const toolSeparator = toolName.indexOf("__", "mcp__".length);
|
|
@@ -114,12 +76,20 @@ export function isWorkflowAliasTool(toolName: string): boolean {
|
|
|
114
76
|
|
|
115
77
|
function hardBlockReason(unitType: string, what: string): string {
|
|
116
78
|
return [
|
|
117
|
-
`HARD BLOCK: unit "${unitType}"
|
|
79
|
+
`HARD BLOCK: Tool Contract failure for unit "${unitType}" — ${what}.`,
|
|
118
80
|
"This is a mechanical phase-boundary gate. You MUST NOT proceed, retry the same call,",
|
|
119
81
|
"or route around this block; the orchestrator owns phase transitions.",
|
|
120
82
|
].join(" ");
|
|
121
83
|
}
|
|
122
84
|
|
|
85
|
+
function hardBlock(unitType: string, what: string): AutoUnitToolScopeResult {
|
|
86
|
+
return {
|
|
87
|
+
block: true,
|
|
88
|
+
reason: hardBlockReason(unitType, what),
|
|
89
|
+
displayReason: GSD_PHASE_SCOPE_DISPLAY_REASON,
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
|
|
123
93
|
function allowedGsdToolsForUnit(unitType: string): string[] {
|
|
124
94
|
return [...new Set(
|
|
125
95
|
(AUTO_UNIT_SCOPED_TOOLS[unitType] ?? [])
|
|
@@ -144,7 +114,7 @@ function shouldBlockTaskCompletionScope(
|
|
|
144
114
|
unitId: string | undefined,
|
|
145
115
|
toolName: string,
|
|
146
116
|
input: unknown,
|
|
147
|
-
):
|
|
117
|
+
): AutoUnitToolScopeResult {
|
|
148
118
|
if (!EXECUTE_TASK_UNIT_TYPES.has(unitType)) return { block: false };
|
|
149
119
|
if (canonicalWorkflowToolName(toolName) !== "gsd_task_complete") return { block: false };
|
|
150
120
|
if (!unitId) return { block: false };
|
|
@@ -165,13 +135,10 @@ function shouldBlockTaskCompletionScope(
|
|
|
165
135
|
return { block: false };
|
|
166
136
|
}
|
|
167
137
|
|
|
168
|
-
return
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
`gsd_task_complete may only complete the active task ${expected.milestone}/${expected.slice}/${expected.task}; requested ${actualMilestone}/${actualSlice}/${actualTask}`,
|
|
173
|
-
),
|
|
174
|
-
};
|
|
138
|
+
return hardBlock(
|
|
139
|
+
unitType,
|
|
140
|
+
`gsd_task_complete may only complete the active task ${expected.milestone}/${expected.slice}/${expected.task}; requested ${actualMilestone}/${actualSlice}/${actualTask}`,
|
|
141
|
+
);
|
|
175
142
|
}
|
|
176
143
|
|
|
177
144
|
export function shouldBlockAutoUnitToolCall(
|
|
@@ -179,15 +146,12 @@ export function shouldBlockAutoUnitToolCall(
|
|
|
179
146
|
toolName: string,
|
|
180
147
|
input?: unknown,
|
|
181
148
|
unitId?: string,
|
|
182
|
-
):
|
|
149
|
+
): AutoUnitToolScopeResult {
|
|
183
150
|
const scopedTools = AUTO_UNIT_SCOPED_TOOLS[unitType];
|
|
184
151
|
if (!scopedTools) return { block: false };
|
|
185
152
|
|
|
186
153
|
if (isNativeWorkflowTool(toolName)) {
|
|
187
|
-
return
|
|
188
|
-
block: true,
|
|
189
|
-
reason: hardBlockReason(unitType, "native Workflow is not permitted inside a dispatched GSD auto-mode unit"),
|
|
190
|
-
};
|
|
154
|
+
return hardBlock(unitType, "native Workflow is not permitted inside a dispatched GSD auto-mode unit");
|
|
191
155
|
}
|
|
192
156
|
|
|
193
157
|
const taskScope = shouldBlockTaskCompletionScope(unitType, unitId, toolName, input);
|
|
@@ -199,11 +163,16 @@ export function shouldBlockAutoUnitToolCall(
|
|
|
199
163
|
const allowedTools = allowedGsdToolsForUnit(unitType);
|
|
200
164
|
if (allowedTools.includes(canonicalTool)) return { block: false };
|
|
201
165
|
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
166
|
+
const forbiddenReason = getForbiddenGsdToolReason(unitType, canonicalTool);
|
|
167
|
+
if (forbiddenReason) {
|
|
168
|
+
return hardBlock(
|
|
205
169
|
unitType,
|
|
206
|
-
`GSD lifecycle tool "${canonicalTool}" is not permitted;
|
|
207
|
-
)
|
|
208
|
-
}
|
|
170
|
+
`GSD lifecycle tool "${canonicalTool}" is not permitted; ${forbiddenReason} Fix unit-tool-contracts.ts or the ${unitType} prompt.`,
|
|
171
|
+
);
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
return hardBlock(
|
|
175
|
+
unitType,
|
|
176
|
+
`GSD lifecycle tool "${canonicalTool}" is not permitted; allowed GSD tools: ${allowedTools.length > 0 ? allowedTools.join(", ") : "(none)"}`,
|
|
177
|
+
);
|
|
209
178
|
}
|
|
@@ -83,6 +83,11 @@ import {
|
|
|
83
83
|
nativeWorktreeList,
|
|
84
84
|
nativeLsFiles,
|
|
85
85
|
} from "./native-git-bridge.js";
|
|
86
|
+
import {
|
|
87
|
+
CLOSEOUT_CONSISTENCY_BLOCKED_REASON,
|
|
88
|
+
checkCloseoutConsistencyGate,
|
|
89
|
+
formatCloseoutConsistencyBlock,
|
|
90
|
+
} from "./closeout-consistency-gate.js";
|
|
86
91
|
import { gsdHome } from "./gsd-home.js";
|
|
87
92
|
import { type MilestoneScope, type GsdWorkspace, createWorkspace } from "./workspace.js";
|
|
88
93
|
import {
|
|
@@ -1771,16 +1776,29 @@ export function mergeMilestoneToMain(
|
|
|
1771
1776
|
// symlink layout) — ATTACHing a WAL-mode file to itself corrupts the
|
|
1772
1777
|
// database (#2823).
|
|
1773
1778
|
if (isDbAvailable()) {
|
|
1779
|
+
const contract = resolveGsdPathContract(worktreeCwd, originalBasePath_);
|
|
1780
|
+
const worktreeDbPath = join(contract.worktreeGsd ?? join(worktreeCwd, ".gsd"), "gsd.db");
|
|
1781
|
+
const mainDbPath = contract.projectDb;
|
|
1774
1782
|
try {
|
|
1775
|
-
const
|
|
1776
|
-
|
|
1777
|
-
|
|
1783
|
+
const activeDbPath = getDbPath();
|
|
1784
|
+
if (activeDbPath && _shouldReconcileWorktreeDb(activeDbPath, mainDbPath)) {
|
|
1785
|
+
closeDatabase();
|
|
1786
|
+
if (!openDatabase(mainDbPath)) {
|
|
1787
|
+
throw new Error(`cannot open project DB at ${mainDbPath}`);
|
|
1788
|
+
}
|
|
1789
|
+
}
|
|
1778
1790
|
if (_shouldReconcileWorktreeDb(worktreeDbPath, mainDbPath)) {
|
|
1779
1791
|
reconcileWorktreeDb(mainDbPath, worktreeDbPath);
|
|
1780
1792
|
}
|
|
1781
1793
|
} catch (err) {
|
|
1782
|
-
|
|
1783
|
-
logError("worktree",
|
|
1794
|
+
const message = `DB reconciliation failed before milestone ${milestoneId} merge: ${err instanceof Error ? err.message : String(err)}`;
|
|
1795
|
+
logError("worktree", message);
|
|
1796
|
+
throw new GSDError(GSD_GIT_ERROR, `${message}. Recovery reason: ${CLOSEOUT_CONSISTENCY_BLOCKED_REASON}.`);
|
|
1797
|
+
}
|
|
1798
|
+
|
|
1799
|
+
const closeoutGate = checkCloseoutConsistencyGate(milestoneId);
|
|
1800
|
+
if (!closeoutGate.ok) {
|
|
1801
|
+
throw new GSDError(GSD_GIT_ERROR, formatCloseoutConsistencyBlock(closeoutGate));
|
|
1784
1802
|
}
|
|
1785
1803
|
}
|
|
1786
1804
|
|
|
@@ -107,7 +107,7 @@ import {
|
|
|
107
107
|
} from "./auto-tool-tracking.js";
|
|
108
108
|
import { closeoutUnit } from "./auto-unit-closeout.js";
|
|
109
109
|
import { recoverTimedOutUnit } from "./auto-timeout-recovery.js";
|
|
110
|
-
import { selectAndApplyModel, resolveModelId, clearToolBaseline } from "./auto-model-selection.js";
|
|
110
|
+
import { selectAndApplyModel, resolveModelId, clearToolBaseline, getToolBaselineSnapshot } from "./auto-model-selection.js";
|
|
111
111
|
import { resetRoutingHistory, recordOutcome } from "./routing-history.js";
|
|
112
112
|
import {
|
|
113
113
|
checkPostUnitHooks,
|
|
@@ -542,8 +542,26 @@ function handlePausedSessionResumeRecovery(
|
|
|
542
542
|
): { skippedReplay: boolean } {
|
|
543
543
|
if (!state.pausedSessionFile) return { skippedReplay: false };
|
|
544
544
|
|
|
545
|
-
const pausedRecoveryUnitType = state.currentUnit?.type ?? state.pausedUnitType ??
|
|
546
|
-
const pausedRecoveryUnitId = state.currentUnit?.id ?? state.pausedUnitId ??
|
|
545
|
+
const pausedRecoveryUnitType = state.currentUnit?.type ?? state.pausedUnitType ?? null;
|
|
546
|
+
const pausedRecoveryUnitId = state.currentUnit?.id ?? state.pausedUnitId ?? null;
|
|
547
|
+
|
|
548
|
+
// When the paused-session metadata never captured the unit identity (the
|
|
549
|
+
// pause happened between units, or the worker died before currentUnit was
|
|
550
|
+
// set), we have nothing to verify against and nothing correct to target. A
|
|
551
|
+
// replay synthesized with an "unknown" unit re-injects an unbounded,
|
|
552
|
+
// mis-identified tool-call blob into the fresh resume context — exactly the
|
|
553
|
+
// thrash that turns one stuck unit into several. Disk state has already been
|
|
554
|
+
// rebuilt (rebuildState + doctor) before this runs, so skip the replay and
|
|
555
|
+
// let the normal dispatcher recompute the next unit from disk.
|
|
556
|
+
if (!pausedRecoveryUnitType || !pausedRecoveryUnitId) {
|
|
557
|
+
state.pausedSessionFile = null;
|
|
558
|
+
state.pausedUnitType = null;
|
|
559
|
+
state.pausedUnitId = null;
|
|
560
|
+
state.pendingCrashRecovery = null;
|
|
561
|
+
notify("Paused session had no recorded unit identity. Skipping tool-call replay and resuming from disk state.");
|
|
562
|
+
return { skippedReplay: true };
|
|
563
|
+
}
|
|
564
|
+
|
|
547
565
|
const completedPausedUnit = verifyExpectedArtifact(
|
|
548
566
|
pausedRecoveryUnitType,
|
|
549
567
|
pausedRecoveryUnitId,
|
|
@@ -2154,7 +2172,10 @@ export function createWiredDispatchAdapter(
|
|
|
2154
2172
|
sessionProvider && typeof ctx.modelRegistry?.getProviderAuthMode === "function"
|
|
2155
2173
|
? ctx.modelRegistry.getProviderAuthMode(sessionProvider)
|
|
2156
2174
|
: undefined;
|
|
2157
|
-
|
|
2175
|
+
// Use baseline snapshot — same reason as phases.ts:runDispatch: the live
|
|
2176
|
+
// active set may be narrowed by the prior unit before selectAndApplyModel
|
|
2177
|
+
// restores it, causing false transport-preflight failures (#477 follow-up).
|
|
2178
|
+
const activeTools = getToolBaselineSnapshot(pi);
|
|
2158
2179
|
// Mirrors runDispatch: deep-planning keeps approval gates in plain chat
|
|
2159
2180
|
// because structured questions can be cancelled outside the chat turn on
|
|
2160
2181
|
// some transports.
|
|
@@ -2201,6 +2222,9 @@ export function createWiredDispatchAdapter(
|
|
|
2201
2222
|
sessionContextWindow,
|
|
2202
2223
|
sessionProvider,
|
|
2203
2224
|
modelRegistry,
|
|
2225
|
+
activeTools,
|
|
2226
|
+
sessionAuthMode: authMode,
|
|
2227
|
+
sessionBaseUrl: ctx.model?.baseUrl,
|
|
2204
2228
|
});
|
|
2205
2229
|
|
|
2206
2230
|
if (action.action === "stop") {
|
|
@@ -78,6 +78,9 @@ function readDetails(result: any): any {
|
|
|
78
78
|
|
|
79
79
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- result shape varies by tool
|
|
80
80
|
function formatToolErrorText(result: any, details: any): string {
|
|
81
|
+
if (typeof details?.displayReason === "string" && details.displayReason) {
|
|
82
|
+
return details.displayReason;
|
|
83
|
+
}
|
|
81
84
|
const message = details?.error
|
|
82
85
|
?? result?.content?.find((entry: { type?: string; text?: string }) => entry.type === "text")?.text
|
|
83
86
|
?? "unknown";
|
|
@@ -424,6 +427,9 @@ export function registerDbTools(pi: ExtensionAPI): void {
|
|
|
424
427
|
kind: StringEnum(["gsd_uat_exec", "gsd_exec", "screenshot", "log", "url", "browser"], { description: "Evidence kind" }),
|
|
425
428
|
ref: Type.String({ description: "Evidence ID, approved .gsd path, or URL" }),
|
|
426
429
|
note: Type.Optional(Type.String({ description: "Short evidence note" })),
|
|
430
|
+
unitType: Type.Optional(Type.String({ description: "Unit that produced the evidence" })),
|
|
431
|
+
tool: Type.Optional(Type.String({ description: "Tool that produced the evidence" })),
|
|
432
|
+
executionId: Type.Optional(Type.String({ description: "Stable execution or artifact id" })),
|
|
427
433
|
});
|
|
428
434
|
|
|
429
435
|
const uatCheck = Type.Object({
|
|
@@ -437,17 +443,17 @@ export function registerDbTools(pi: ExtensionAPI): void {
|
|
|
437
443
|
});
|
|
438
444
|
|
|
439
445
|
const toolPresentationBlock = Type.Object({
|
|
440
|
-
surface: StringEnum(["provider-tools", "claude-code-sdk", "mcp", "hybrid"], { description: "Tool presentation surface" }),
|
|
446
|
+
surface: Type.Optional(StringEnum(["provider-tools", "claude-code-sdk", "mcp", "hybrid"], { description: "Tool presentation surface" })),
|
|
441
447
|
model: Type.Optional(Type.Object({
|
|
442
448
|
provider: Type.Optional(Type.String()),
|
|
443
449
|
api: Type.Optional(Type.String()),
|
|
444
450
|
id: Type.Optional(Type.String()),
|
|
445
451
|
})),
|
|
446
|
-
presentedTools: Type.Array(Type.String(), { description: "Tool names actually presented to the model" }),
|
|
447
|
-
blockedTools: Type.Array(Type.Object({
|
|
452
|
+
presentedTools: Type.Optional(Type.Array(Type.String(), { description: "Tool names actually presented to the model" })),
|
|
453
|
+
blockedTools: Type.Optional(Type.Array(Type.Object({
|
|
448
454
|
name: Type.String(),
|
|
449
455
|
reason: Type.String(),
|
|
450
|
-
}), { description: "Tool names blocked from the model with reasons" }),
|
|
456
|
+
}), { description: "Tool names blocked from the model with reasons" })),
|
|
451
457
|
aliases: Type.Optional(Type.Array(Type.Object({
|
|
452
458
|
requested: Type.String(),
|
|
453
459
|
canonical: Type.String(),
|
|
@@ -471,12 +477,12 @@ export function registerDbTools(pi: ExtensionAPI): void {
|
|
|
471
477
|
"Do not use raw gsd_summary_save as a substitute for UAT results.",
|
|
472
478
|
],
|
|
473
479
|
parameters: Type.Object({
|
|
474
|
-
milestoneId: Type.String({ description: "Milestone ID (e.g. M001)" }),
|
|
475
|
-
sliceId: Type.String({ description: "Slice ID (e.g. S01)" }),
|
|
476
|
-
uatType:
|
|
477
|
-
verdict:
|
|
478
|
-
checks: Type.Array(uatCheck, { description: "Structured check results" }),
|
|
479
|
-
presentation: toolPresentationBlock,
|
|
480
|
+
milestoneId: Type.Optional(Type.String({ description: "Milestone ID (e.g. M001)" })),
|
|
481
|
+
sliceId: Type.Optional(Type.String({ description: "Slice ID (e.g. S01)" })),
|
|
482
|
+
uatType: Type.Optional(Type.String({ description: "Declared UAT mode" })),
|
|
483
|
+
verdict: Type.Optional(Type.String({ description: "Overall UAT verdict: PASS, FAIL, or PARTIAL" })),
|
|
484
|
+
checks: Type.Optional(Type.Array(uatCheck, { description: "Structured check results" })),
|
|
485
|
+
presentation: Type.Optional(toolPresentationBlock),
|
|
480
486
|
notes: Type.Optional(Type.String({ description: "Overall verdict rationale" })),
|
|
481
487
|
attempt: Type.Optional(Type.String({ description: "Attempt number or auto" })),
|
|
482
488
|
previousAttemptId: Type.Optional(Type.String({ description: "Prior attempt ID, when retrying" })),
|
|
@@ -38,7 +38,7 @@ import { getGuidedUnitContext } from "../guided-unit-context.js";
|
|
|
38
38
|
import { registerPlanMilestoneSchemaRecovery } from "./plan-milestone-schema-recovery.js";
|
|
39
39
|
import { AUTO_UNIT_SCOPED_TOOLS, RUN_UAT_BROWSER_TOOL_NAMES, isWorkflowAliasTool } from "../auto-unit-tool-scope.js";
|
|
40
40
|
import { filterToolsForProvider } from "../model-router.js";
|
|
41
|
-
import { RUN_UAT_WORKFLOW_TOOL_NAMES } from "../tool-presentation-plan.js";
|
|
41
|
+
import { RUN_UAT_READ_ONLY_TOOL_NAMES, RUN_UAT_WORKFLOW_TOOL_NAMES } from "../tool-presentation-plan.js";
|
|
42
42
|
|
|
43
43
|
let approvalQuestionAbortInFlight = false;
|
|
44
44
|
|
|
@@ -252,9 +252,26 @@ export function buildRunUatGsdToolSet(
|
|
|
252
252
|
): string[] {
|
|
253
253
|
const scoped = resolveScopedToolNames(
|
|
254
254
|
[...activeToolNames, ...registeredToolNames],
|
|
255
|
-
[
|
|
255
|
+
[
|
|
256
|
+
...RUN_UAT_WORKFLOW_TOOL_NAMES,
|
|
257
|
+
...RUN_UAT_READ_ONLY_TOOL_NAMES,
|
|
258
|
+
"subagent",
|
|
259
|
+
...RUN_UAT_BROWSER_TOOL_NAMES,
|
|
260
|
+
],
|
|
256
261
|
);
|
|
257
|
-
|
|
262
|
+
const resolved = [...new Set(scoped)];
|
|
263
|
+
|
|
264
|
+
const unresolved = RUN_UAT_WORKFLOW_TOOL_NAMES.filter(
|
|
265
|
+
(tool) => !resolved.some((name) => name === tool || (name.startsWith("mcp__") && name.endsWith(`__${tool}`))),
|
|
266
|
+
);
|
|
267
|
+
if (unresolved.length > 0) {
|
|
268
|
+
safetyLogWarning(
|
|
269
|
+
"bootstrap",
|
|
270
|
+
`buildRunUatGsdToolSet: required run-uat workflow tool(s) not found in active/registered surface: ${unresolved.join(", ")}. Session may lack gsd-workflow MCP connection.`,
|
|
271
|
+
);
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
return resolved;
|
|
258
275
|
}
|
|
259
276
|
|
|
260
277
|
export function buildMinimalGsdWorkflowToolSet(
|
|
@@ -480,22 +497,30 @@ function isContextDraftSummarySave(toolName: string, input: unknown): boolean {
|
|
|
480
497
|
return (input as { artifact_type?: unknown }).artifact_type === "CONTEXT-DRAFT";
|
|
481
498
|
}
|
|
482
499
|
|
|
500
|
+
function withDepthGateDisplayReason<T extends { block: boolean; reason?: string }>(
|
|
501
|
+
result: T,
|
|
502
|
+
displayReason = "Depth confirmation is waiting for your answer.",
|
|
503
|
+
): T & { displayReason?: string } {
|
|
504
|
+
if (!result.block) return result;
|
|
505
|
+
return { ...result, displayReason };
|
|
506
|
+
}
|
|
507
|
+
|
|
483
508
|
function shouldBlockDeferredApprovalTool(
|
|
484
509
|
toolName: string,
|
|
485
510
|
input: unknown,
|
|
486
511
|
basePath: string,
|
|
487
|
-
): { block: boolean; reason?: string } {
|
|
512
|
+
): { block: boolean; reason?: string; displayReason?: string } {
|
|
488
513
|
if (deferredApprovalGate?.basePath !== basePath) return { block: false };
|
|
489
514
|
if (toolName === "ask_user_questions") return { block: false };
|
|
490
515
|
if (isContextDraftSummarySave(toolName, input)) return { block: false };
|
|
491
|
-
return {
|
|
516
|
+
return withDepthGateDisplayReason({
|
|
492
517
|
block: true,
|
|
493
518
|
reason: [
|
|
494
519
|
`HARD BLOCK: Approval question "${deferredApprovalGate.gateId}" has been shown to the user.`,
|
|
495
520
|
`Only CONTEXT-DRAFT persistence may finish in this same assistant turn.`,
|
|
496
521
|
`Wait for the user's answer before calling additional tools.`,
|
|
497
522
|
].join(" "),
|
|
498
|
-
};
|
|
523
|
+
});
|
|
499
524
|
}
|
|
500
525
|
|
|
501
526
|
export function resolveNotificationStoreBasePath(basePath: string): string {
|
|
@@ -564,6 +589,17 @@ export function registerHooks(
|
|
|
564
589
|
if (isAutoActive() || preserveCloseoutSurface) {
|
|
565
590
|
ctx.ui.setWidget("gsd-health", undefined);
|
|
566
591
|
}
|
|
592
|
+
// Cold start after /quit relaunches with cwd at the project root. When
|
|
593
|
+
// auto-mode is neither active nor paused (its own resume path re-enters the
|
|
594
|
+
// worktree with a lease check — auto.ts:3032), proactively chdir back into
|
|
595
|
+
// the active milestone's worktree so subsequent work isn't stranded at the
|
|
596
|
+
// root. Best-effort and a no-op when already inside a worktree.
|
|
597
|
+
if (!isAutoActive() && !isAutoPaused() && !preserveCloseoutSurface) {
|
|
598
|
+
try {
|
|
599
|
+
const { reenterActiveWorktreeIfNeeded } = await import("../worktree-reentry.js");
|
|
600
|
+
await reenterActiveWorktreeIfNeeded(basePath);
|
|
601
|
+
} catch { /* non-fatal */ }
|
|
602
|
+
}
|
|
567
603
|
});
|
|
568
604
|
|
|
569
605
|
pi.on("session_switch", async (_event, ctx) => {
|
|
@@ -917,7 +953,7 @@ export function registerHooks(
|
|
|
917
953
|
"Depth confirmation is waiting for your answer — pausing auto-mode.",
|
|
918
954
|
);
|
|
919
955
|
}
|
|
920
|
-
return bashGuard;
|
|
956
|
+
return withDepthGateDisplayReason(bashGuard);
|
|
921
957
|
}
|
|
922
958
|
} else {
|
|
923
959
|
const gateGuard = shouldBlockPendingGate(
|
|
@@ -935,7 +971,7 @@ export function registerHooks(
|
|
|
935
971
|
"Depth confirmation is waiting for your answer — pausing auto-mode.",
|
|
936
972
|
);
|
|
937
973
|
}
|
|
938
|
-
return gateGuard;
|
|
974
|
+
return withDepthGateDisplayReason(gateGuard);
|
|
939
975
|
}
|
|
940
976
|
}
|
|
941
977
|
}
|
|
@@ -1040,7 +1076,9 @@ export function registerHooks(
|
|
|
1040
1076
|
isQueuePhaseActive(discussionBasePath),
|
|
1041
1077
|
discussionBasePath,
|
|
1042
1078
|
);
|
|
1043
|
-
if (result.block)
|
|
1079
|
+
if (result.block) {
|
|
1080
|
+
return withDepthGateDisplayReason(result, "Depth check required before writing milestone context.");
|
|
1081
|
+
}
|
|
1044
1082
|
});
|
|
1045
1083
|
|
|
1046
1084
|
// ── Safety harness: evidence collection + destructive command blocking ──
|
|
@@ -1278,17 +1316,25 @@ export function registerHooks(
|
|
|
1278
1316
|
if (isAutoActive()) {
|
|
1279
1317
|
try {
|
|
1280
1318
|
const { loadEffectiveGSDPreferences } = await import("../preferences.js");
|
|
1319
|
+
const {
|
|
1320
|
+
createObservationMask,
|
|
1321
|
+
createResponsesInputObservationMask,
|
|
1322
|
+
truncateContextResultMessages,
|
|
1323
|
+
truncateResponsesInputResultItems,
|
|
1324
|
+
} = await import("../context-masker.js");
|
|
1281
1325
|
const prefs = loadEffectiveGSDPreferences();
|
|
1282
1326
|
const cmConfig = prefs?.preferences.context_management;
|
|
1283
1327
|
|
|
1284
1328
|
// Observation masking: replace old tool results with placeholders
|
|
1285
1329
|
if (cmConfig?.observation_masking !== false) {
|
|
1286
1330
|
const keepTurns = cmConfig?.observation_mask_turns ?? 8;
|
|
1287
|
-
const { createObservationMask } = await import("../context-masker.js");
|
|
1288
|
-
const mask = createObservationMask(keepTurns);
|
|
1289
1331
|
const messages = payload.messages;
|
|
1290
1332
|
if (Array.isArray(messages)) {
|
|
1291
|
-
payload.messages =
|
|
1333
|
+
payload.messages = createObservationMask(keepTurns)(messages);
|
|
1334
|
+
}
|
|
1335
|
+
const input = payload.input;
|
|
1336
|
+
if (Array.isArray(input)) {
|
|
1337
|
+
payload.input = createResponsesInputObservationMask(keepTurns)(input);
|
|
1292
1338
|
}
|
|
1293
1339
|
}
|
|
1294
1340
|
|
|
@@ -1298,23 +1344,11 @@ export function registerHooks(
|
|
|
1298
1344
|
const maxChars = cmConfig?.tool_result_max_chars ?? 800;
|
|
1299
1345
|
const msgs = payload.messages;
|
|
1300
1346
|
if (Array.isArray(msgs)) {
|
|
1301
|
-
payload.messages = msgs
|
|
1302
|
-
|
|
1303
|
-
|
|
1304
|
-
|
|
1305
|
-
|
|
1306
|
-
if (totalLen > maxChars) {
|
|
1307
|
-
const truncated = blocks.map(b => {
|
|
1308
|
-
if (typeof b.text === "string" && b.text.length > maxChars) {
|
|
1309
|
-
return { ...b, text: b.text.slice(0, maxChars) + "\n…[truncated]" };
|
|
1310
|
-
}
|
|
1311
|
-
return b;
|
|
1312
|
-
});
|
|
1313
|
-
return { ...msg, content: truncated };
|
|
1314
|
-
}
|
|
1315
|
-
}
|
|
1316
|
-
return msg;
|
|
1317
|
-
});
|
|
1347
|
+
payload.messages = truncateContextResultMessages(msgs as any, maxChars);
|
|
1348
|
+
}
|
|
1349
|
+
const input = payload.input;
|
|
1350
|
+
if (Array.isArray(input)) {
|
|
1351
|
+
payload.input = truncateResponsesInputResultItems(input as any, maxChars);
|
|
1318
1352
|
}
|
|
1319
1353
|
} catch { /* non-fatal */ }
|
|
1320
1354
|
}
|
|
@@ -61,7 +61,7 @@ export const BUNDLED_SKILL_TRIGGERS: Array<{ trigger: string; skill: string }> =
|
|
|
61
61
|
{ trigger: "Core Web Vitals — fix LCP, CLS, INP; layout shifts; page experience optimization", skill: "core-web-vitals" },
|
|
62
62
|
{ trigger: "GitHub Actions CI/CD — write, run, and debug workflow files; live syntax and run monitoring", skill: "github-workflows" },
|
|
63
63
|
{ trigger: "Comprehensive web quality audit — performance, accessibility, SEO, and best-practices (Lighthouse-style)", skill: "web-quality-audit" },
|
|
64
|
-
{ trigger: "gsd-browser
|
|
64
|
+
{ trigger: "gsd-browser opt-in and External MCP UAT — screenshots, assertions, console/network diagnostics", skill: "gsd-browser" },
|
|
65
65
|
{ trigger: "Browser automation — open sites, fill forms, click, screenshot, scrape, or test web apps programmatically", skill: "agent-browser" },
|
|
66
66
|
{ trigger: "Review UI code for Web Interface Guidelines compliance — UX, design, and accessibility patterns", skill: "web-design-guidelines" },
|
|
67
67
|
{ trigger: "UI/UX patterns reference — animations, CSS, typography, prefetching, icons (file:line findings)", skill: "userinterface-wiki" },
|