gsd-pi 2.37.1 → 2.38.0-dev.29edcdc
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/README.md +1 -1
- package/dist/app-paths.js +1 -1
- package/dist/cli.js +9 -0
- package/dist/extension-discovery.d.ts +5 -3
- package/dist/extension-discovery.js +14 -9
- package/dist/extension-registry.js +2 -2
- package/dist/onboarding.js +1 -0
- package/dist/remote-questions-config.js +2 -2
- package/dist/resource-loader.js +34 -1
- package/dist/resources/extensions/browser-tools/package.json +3 -1
- package/dist/resources/extensions/cmux/index.js +55 -1
- package/dist/resources/extensions/context7/package.json +1 -1
- package/dist/resources/extensions/env-utils.js +29 -0
- package/dist/resources/extensions/get-secrets-from-user.js +5 -24
- package/dist/resources/extensions/github-sync/cli.js +284 -0
- package/dist/resources/extensions/github-sync/index.js +73 -0
- package/dist/resources/extensions/github-sync/mapping.js +67 -0
- package/dist/resources/extensions/github-sync/sync.js +424 -0
- package/dist/resources/extensions/github-sync/templates.js +118 -0
- package/dist/resources/extensions/github-sync/types.js +7 -0
- package/dist/resources/extensions/google-search/package.json +3 -1
- package/dist/resources/extensions/gsd/auto/session.js +6 -23
- package/dist/resources/extensions/gsd/auto-dispatch.js +75 -10
- package/dist/resources/extensions/gsd/auto-loop.js +597 -588
- package/dist/resources/extensions/gsd/auto-post-unit.js +111 -68
- package/dist/resources/extensions/gsd/auto-prompts.js +114 -45
- package/dist/resources/extensions/gsd/auto-recovery.js +37 -1
- package/dist/resources/extensions/gsd/auto-start.js +13 -2
- package/dist/resources/extensions/gsd/auto-worktree-sync.js +13 -5
- package/dist/resources/extensions/gsd/auto-worktree.js +3 -3
- package/dist/resources/extensions/gsd/auto.js +143 -96
- package/dist/resources/extensions/gsd/captures.js +9 -1
- package/dist/resources/extensions/gsd/commands-extensions.js +3 -2
- package/dist/resources/extensions/gsd/commands-handlers.js +16 -3
- package/dist/resources/extensions/gsd/commands-prefs-wizard.js +1 -1
- package/dist/resources/extensions/gsd/commands.js +24 -3
- package/dist/resources/extensions/gsd/context-budget.js +2 -10
- package/dist/resources/extensions/gsd/detection.js +1 -2
- package/dist/resources/extensions/gsd/docs/preferences-reference.md +0 -2
- package/dist/resources/extensions/gsd/doctor-checks.js +82 -0
- package/dist/resources/extensions/gsd/doctor-environment.js +78 -0
- package/dist/resources/extensions/gsd/doctor-format.js +15 -0
- package/dist/resources/extensions/gsd/doctor-providers.js +62 -12
- package/dist/resources/extensions/gsd/doctor.js +204 -12
- package/dist/resources/extensions/gsd/exit-command.js +2 -1
- package/dist/resources/extensions/gsd/export.js +1 -1
- package/dist/resources/extensions/gsd/files.js +47 -2
- package/dist/resources/extensions/gsd/forensics.js +1 -1
- package/dist/resources/extensions/gsd/git-service.js +15 -12
- package/dist/resources/extensions/gsd/guided-flow.js +82 -32
- package/dist/resources/extensions/gsd/index.js +24 -20
- package/dist/resources/extensions/gsd/migrate/parsers.js +1 -1
- package/dist/resources/extensions/gsd/native-git-bridge.js +37 -0
- package/dist/resources/extensions/gsd/observability-validator.js +24 -0
- package/dist/resources/extensions/gsd/package.json +1 -1
- package/dist/resources/extensions/gsd/preferences-models.js +0 -12
- package/dist/resources/extensions/gsd/preferences-types.js +3 -2
- package/dist/resources/extensions/gsd/preferences-validation.js +101 -11
- package/dist/resources/extensions/gsd/preferences.js +8 -5
- package/dist/resources/extensions/gsd/prompts/discuss.md +11 -14
- package/dist/resources/extensions/gsd/prompts/execute-task.md +2 -2
- package/dist/resources/extensions/gsd/prompts/guided-discuss-milestone.md +11 -12
- package/dist/resources/extensions/gsd/prompts/guided-discuss-slice.md +8 -10
- package/dist/resources/extensions/gsd/prompts/guided-resume-task.md +1 -1
- package/dist/resources/extensions/gsd/prompts/plan-slice.md +2 -1
- package/dist/resources/extensions/gsd/prompts/queue.md +4 -8
- package/dist/resources/extensions/gsd/prompts/reactive-execute.md +44 -0
- package/dist/resources/extensions/gsd/prompts/run-uat.md +27 -10
- package/dist/resources/extensions/gsd/prompts/workflow-start.md +2 -2
- package/dist/resources/extensions/gsd/reactive-graph.js +227 -0
- package/dist/resources/extensions/gsd/repo-identity.js +21 -4
- package/dist/resources/extensions/gsd/resource-version.js +2 -1
- package/dist/resources/extensions/gsd/roadmap-mutations.js +24 -0
- package/dist/resources/extensions/gsd/state.js +1 -1
- package/dist/resources/extensions/gsd/templates/task-plan.md +11 -3
- package/dist/resources/extensions/gsd/visualizer-data.js +1 -1
- package/dist/resources/extensions/gsd/worktree.js +35 -16
- package/dist/resources/extensions/mcp-client/index.js +14 -1
- package/dist/resources/extensions/remote-questions/status.js +2 -1
- package/dist/resources/extensions/remote-questions/store.js +2 -1
- package/dist/resources/extensions/search-the-web/provider.js +2 -1
- package/dist/resources/extensions/subagent/index.js +12 -3
- package/dist/resources/extensions/subagent/isolation.js +2 -1
- package/dist/resources/extensions/ttsr/rule-loader.js +2 -1
- package/dist/resources/extensions/universal-config/package.json +1 -1
- package/dist/welcome-screen.d.ts +12 -0
- package/dist/welcome-screen.js +53 -0
- package/package.json +2 -1
- package/packages/pi-ai/dist/env-api-keys.js +13 -0
- package/packages/pi-ai/dist/env-api-keys.js.map +1 -1
- package/packages/pi-ai/dist/models.generated.d.ts +172 -0
- package/packages/pi-ai/dist/models.generated.d.ts.map +1 -1
- package/packages/pi-ai/dist/models.generated.js +172 -0
- package/packages/pi-ai/dist/models.generated.js.map +1 -1
- package/packages/pi-ai/dist/providers/anthropic-shared.d.ts +64 -0
- package/packages/pi-ai/dist/providers/anthropic-shared.d.ts.map +1 -0
- package/packages/pi-ai/dist/providers/anthropic-shared.js +668 -0
- package/packages/pi-ai/dist/providers/anthropic-shared.js.map +1 -0
- package/packages/pi-ai/dist/providers/anthropic-vertex.d.ts +5 -0
- package/packages/pi-ai/dist/providers/anthropic-vertex.d.ts.map +1 -0
- package/packages/pi-ai/dist/providers/anthropic-vertex.js +85 -0
- package/packages/pi-ai/dist/providers/anthropic-vertex.js.map +1 -0
- package/packages/pi-ai/dist/providers/anthropic.d.ts +4 -30
- package/packages/pi-ai/dist/providers/anthropic.d.ts.map +1 -1
- package/packages/pi-ai/dist/providers/anthropic.js +47 -764
- package/packages/pi-ai/dist/providers/anthropic.js.map +1 -1
- package/packages/pi-ai/dist/providers/register-builtins.d.ts.map +1 -1
- package/packages/pi-ai/dist/providers/register-builtins.js +6 -0
- package/packages/pi-ai/dist/providers/register-builtins.js.map +1 -1
- package/packages/pi-ai/dist/types.d.ts +2 -2
- package/packages/pi-ai/dist/types.d.ts.map +1 -1
- package/packages/pi-ai/dist/types.js.map +1 -1
- package/packages/pi-ai/dist/utils/oauth/anthropic.js +2 -2
- package/packages/pi-ai/dist/utils/oauth/anthropic.js.map +1 -1
- package/packages/pi-ai/package.json +1 -0
- package/packages/pi-ai/src/env-api-keys.ts +14 -0
- package/packages/pi-ai/src/models.generated.ts +172 -0
- package/packages/pi-ai/src/providers/anthropic-shared.ts +761 -0
- package/packages/pi-ai/src/providers/anthropic-vertex.ts +130 -0
- package/packages/pi-ai/src/providers/anthropic.ts +76 -868
- package/packages/pi-ai/src/providers/register-builtins.ts +7 -0
- package/packages/pi-ai/src/types.ts +2 -0
- package/packages/pi-ai/src/utils/oauth/anthropic.ts +2 -2
- package/packages/pi-coding-agent/dist/core/extensions/loader.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/extensions/loader.js +205 -7
- package/packages/pi-coding-agent/dist/core/extensions/loader.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/model-resolver.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/model-resolver.js +1 -0
- package/packages/pi-coding-agent/dist/core/model-resolver.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/package-manager.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/package-manager.js +8 -4
- package/packages/pi-coding-agent/dist/core/package-manager.js.map +1 -1
- package/packages/pi-coding-agent/package.json +1 -1
- package/packages/pi-coding-agent/src/core/extensions/loader.ts +223 -7
- package/packages/pi-coding-agent/src/core/model-resolver.ts +1 -0
- package/packages/pi-coding-agent/src/core/package-manager.ts +8 -4
- package/pkg/package.json +1 -1
- package/src/resources/extensions/cmux/index.ts +57 -1
- package/src/resources/extensions/env-utils.ts +31 -0
- package/src/resources/extensions/get-secrets-from-user.ts +5 -24
- package/src/resources/extensions/github-sync/cli.ts +364 -0
- package/src/resources/extensions/github-sync/index.ts +93 -0
- package/src/resources/extensions/github-sync/mapping.ts +81 -0
- package/src/resources/extensions/github-sync/sync.ts +556 -0
- package/src/resources/extensions/github-sync/templates.ts +183 -0
- package/src/resources/extensions/github-sync/tests/cli.test.ts +20 -0
- package/src/resources/extensions/github-sync/tests/commit-linking.test.ts +39 -0
- package/src/resources/extensions/github-sync/tests/mapping.test.ts +104 -0
- package/src/resources/extensions/github-sync/tests/templates.test.ts +110 -0
- package/src/resources/extensions/github-sync/types.ts +47 -0
- package/src/resources/extensions/gsd/auto/session.ts +7 -25
- package/src/resources/extensions/gsd/auto-dispatch.ts +100 -9
- package/src/resources/extensions/gsd/auto-loop.ts +484 -546
- package/src/resources/extensions/gsd/auto-post-unit.ts +92 -42
- package/src/resources/extensions/gsd/auto-prompts.ts +150 -48
- package/src/resources/extensions/gsd/auto-recovery.ts +42 -0
- package/src/resources/extensions/gsd/auto-start.ts +18 -2
- package/src/resources/extensions/gsd/auto-worktree-sync.ts +15 -4
- package/src/resources/extensions/gsd/auto-worktree.ts +3 -3
- package/src/resources/extensions/gsd/auto.ts +139 -101
- package/src/resources/extensions/gsd/captures.ts +10 -1
- package/src/resources/extensions/gsd/commands-extensions.ts +4 -2
- package/src/resources/extensions/gsd/commands-handlers.ts +17 -2
- package/src/resources/extensions/gsd/commands-prefs-wizard.ts +1 -1
- package/src/resources/extensions/gsd/commands.ts +26 -4
- package/src/resources/extensions/gsd/context-budget.ts +2 -12
- package/src/resources/extensions/gsd/detection.ts +2 -2
- package/src/resources/extensions/gsd/docs/preferences-reference.md +0 -2
- package/src/resources/extensions/gsd/doctor-checks.ts +75 -0
- package/src/resources/extensions/gsd/doctor-environment.ts +82 -1
- package/src/resources/extensions/gsd/doctor-format.ts +20 -0
- package/src/resources/extensions/gsd/doctor-providers.ts +64 -10
- package/src/resources/extensions/gsd/doctor-types.ts +16 -1
- package/src/resources/extensions/gsd/doctor.ts +199 -14
- package/src/resources/extensions/gsd/exit-command.ts +2 -2
- package/src/resources/extensions/gsd/export.ts +1 -1
- package/src/resources/extensions/gsd/files.ts +50 -3
- package/src/resources/extensions/gsd/forensics.ts +1 -1
- package/src/resources/extensions/gsd/git-service.ts +20 -10
- package/src/resources/extensions/gsd/guided-flow.ts +110 -38
- package/src/resources/extensions/gsd/index.ts +24 -17
- package/src/resources/extensions/gsd/migrate/parsers.ts +1 -1
- package/src/resources/extensions/gsd/native-git-bridge.ts +37 -0
- package/src/resources/extensions/gsd/observability-validator.ts +27 -0
- package/src/resources/extensions/gsd/preferences-models.ts +0 -12
- package/src/resources/extensions/gsd/preferences-types.ts +9 -5
- package/src/resources/extensions/gsd/preferences-validation.ts +92 -11
- package/src/resources/extensions/gsd/preferences.ts +8 -5
- package/src/resources/extensions/gsd/prompts/discuss.md +11 -14
- package/src/resources/extensions/gsd/prompts/execute-task.md +2 -2
- package/src/resources/extensions/gsd/prompts/guided-discuss-milestone.md +11 -12
- package/src/resources/extensions/gsd/prompts/guided-discuss-slice.md +8 -10
- package/src/resources/extensions/gsd/prompts/guided-resume-task.md +1 -1
- package/src/resources/extensions/gsd/prompts/plan-slice.md +2 -1
- package/src/resources/extensions/gsd/prompts/queue.md +4 -8
- package/src/resources/extensions/gsd/prompts/reactive-execute.md +44 -0
- package/src/resources/extensions/gsd/prompts/run-uat.md +27 -10
- package/src/resources/extensions/gsd/prompts/workflow-start.md +2 -2
- package/src/resources/extensions/gsd/reactive-graph.ts +289 -0
- package/src/resources/extensions/gsd/repo-identity.ts +23 -4
- package/src/resources/extensions/gsd/resource-version.ts +3 -1
- package/src/resources/extensions/gsd/roadmap-mutations.ts +29 -0
- package/src/resources/extensions/gsd/state.ts +1 -1
- package/src/resources/extensions/gsd/templates/task-plan.md +11 -3
- package/src/resources/extensions/gsd/tests/agent-end-retry.test.ts +21 -18
- package/src/resources/extensions/gsd/tests/auto-loop.test.ts +122 -68
- package/src/resources/extensions/gsd/tests/cmux.test.ts +93 -0
- package/src/resources/extensions/gsd/tests/doctor-enhancements.test.ts +266 -0
- package/src/resources/extensions/gsd/tests/doctor-providers.test.ts +191 -3
- package/src/resources/extensions/gsd/tests/plan-quality-validator.test.ts +111 -0
- package/src/resources/extensions/gsd/tests/preferences.test.ts +2 -7
- package/src/resources/extensions/gsd/tests/prompt-contracts.test.ts +59 -0
- package/src/resources/extensions/gsd/tests/reactive-executor.test.ts +511 -0
- package/src/resources/extensions/gsd/tests/reactive-graph.test.ts +299 -0
- package/src/resources/extensions/gsd/tests/repo-identity-worktree.test.ts +21 -1
- package/src/resources/extensions/gsd/tests/run-uat.test.ts +11 -3
- package/src/resources/extensions/gsd/tests/worktree.test.ts +47 -0
- package/src/resources/extensions/gsd/types.ts +43 -1
- package/src/resources/extensions/gsd/visualizer-data.ts +1 -1
- package/src/resources/extensions/gsd/worktree.ts +35 -15
- package/src/resources/extensions/mcp-client/index.ts +17 -1
- package/src/resources/extensions/remote-questions/status.ts +3 -1
- package/src/resources/extensions/remote-questions/store.ts +3 -1
- package/src/resources/extensions/search-the-web/provider.ts +2 -1
- package/src/resources/extensions/subagent/index.ts +12 -3
- package/src/resources/extensions/subagent/isolation.ts +3 -1
- package/src/resources/extensions/ttsr/rule-loader.ts +3 -1
- package/dist/resources/extensions/gsd/prompt-compressor.js +0 -393
- package/dist/resources/extensions/gsd/semantic-chunker.js +0 -254
- package/dist/resources/extensions/gsd/summary-distiller.js +0 -212
- package/src/resources/extensions/gsd/prompt-compressor.ts +0 -508
- package/src/resources/extensions/gsd/semantic-chunker.ts +0 -336
- package/src/resources/extensions/gsd/summary-distiller.ts +0 -258
- package/src/resources/extensions/gsd/tests/context-compression.test.ts +0 -193
- package/src/resources/extensions/gsd/tests/prompt-compressor.test.ts +0 -529
- package/src/resources/extensions/gsd/tests/semantic-chunker.test.ts +0 -426
- package/src/resources/extensions/gsd/tests/summary-distiller.test.ts +0 -323
- package/src/resources/extensions/gsd/tests/token-optimization-benchmark.test.ts +0 -1272
- package/src/resources/extensions/gsd/tests/token-optimization-prefs.test.ts +0 -164
|
@@ -23,6 +23,12 @@ import * as _bundledYaml from "yaml";
|
|
|
23
23
|
import * as _bundledMcpClient from "@modelcontextprotocol/sdk/client";
|
|
24
24
|
import * as _bundledMcpStdio from "@modelcontextprotocol/sdk/client/stdio.js";
|
|
25
25
|
import * as _bundledMcpStreamableHttp from "@modelcontextprotocol/sdk/client/streamableHttp.js";
|
|
26
|
+
import * as _bundledMcpSse from "@modelcontextprotocol/sdk/client/sse.js";
|
|
27
|
+
import * as _bundledMcpServer from "@modelcontextprotocol/sdk/server";
|
|
28
|
+
import * as _bundledMcpServerStdio from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
29
|
+
import * as _bundledMcpServerSse from "@modelcontextprotocol/sdk/server/sse.js";
|
|
30
|
+
import * as _bundledMcpServerStreamableHttp from "@modelcontextprotocol/sdk/server/streamableHttp.js";
|
|
31
|
+
import * as _bundledMcpTypes from "@modelcontextprotocol/sdk/types.js";
|
|
26
32
|
import { getAgentDir, isBunBinary } from "../../config.js";
|
|
27
33
|
// NOTE: This import works because loader.ts exports are NOT re-exported from index.ts,
|
|
28
34
|
// avoiding a circular dependency. Extensions can import from @gsd/pi-coding-agent.
|
|
@@ -44,8 +50,11 @@ import type {
|
|
|
44
50
|
ToolDefinition,
|
|
45
51
|
} from "./types.js";
|
|
46
52
|
|
|
47
|
-
/**
|
|
48
|
-
|
|
53
|
+
/**
|
|
54
|
+
* Statically imported modules for Bun binary virtualModules.
|
|
55
|
+
* Maps specifier -> module object for subpaths that must be available in compiled binaries.
|
|
56
|
+
*/
|
|
57
|
+
const STATIC_BUNDLED_MODULES: Record<string, unknown> = {
|
|
49
58
|
"@sinclair/typebox": _bundledTypebox,
|
|
50
59
|
"@gsd/pi-agent-core": _bundledPiAgentCore,
|
|
51
60
|
"@gsd/pi-tui": _bundledPiTui,
|
|
@@ -58,6 +67,17 @@ const VIRTUAL_MODULES: Record<string, unknown> = {
|
|
|
58
67
|
"@modelcontextprotocol/sdk/client/stdio.js": _bundledMcpStdio,
|
|
59
68
|
"@modelcontextprotocol/sdk/client/streamableHttp": _bundledMcpStreamableHttp,
|
|
60
69
|
"@modelcontextprotocol/sdk/client/streamableHttp.js": _bundledMcpStreamableHttp,
|
|
70
|
+
"@modelcontextprotocol/sdk/client/sse": _bundledMcpSse,
|
|
71
|
+
"@modelcontextprotocol/sdk/client/sse.js": _bundledMcpSse,
|
|
72
|
+
"@modelcontextprotocol/sdk/server": _bundledMcpServer,
|
|
73
|
+
"@modelcontextprotocol/sdk/server/stdio": _bundledMcpServerStdio,
|
|
74
|
+
"@modelcontextprotocol/sdk/server/stdio.js": _bundledMcpServerStdio,
|
|
75
|
+
"@modelcontextprotocol/sdk/server/sse": _bundledMcpServerSse,
|
|
76
|
+
"@modelcontextprotocol/sdk/server/sse.js": _bundledMcpServerSse,
|
|
77
|
+
"@modelcontextprotocol/sdk/server/streamableHttp": _bundledMcpServerStreamableHttp,
|
|
78
|
+
"@modelcontextprotocol/sdk/server/streamableHttp.js": _bundledMcpServerStreamableHttp,
|
|
79
|
+
"@modelcontextprotocol/sdk/types": _bundledMcpTypes,
|
|
80
|
+
"@modelcontextprotocol/sdk/types.js": _bundledMcpTypes,
|
|
61
81
|
// Aliases for external PI ecosystem packages that import from the original scope
|
|
62
82
|
"@mariozechner/pi-agent-core": _bundledPiAgentCore,
|
|
63
83
|
"@mariozechner/pi-tui": _bundledPiTui,
|
|
@@ -66,9 +86,198 @@ const VIRTUAL_MODULES: Record<string, unknown> = {
|
|
|
66
86
|
"@mariozechner/pi-coding-agent": _bundledPiCodingAgent,
|
|
67
87
|
};
|
|
68
88
|
|
|
89
|
+
/** Modules available to extensions via virtualModules (for compiled Bun binary) */
|
|
90
|
+
const VIRTUAL_MODULES: Record<string, unknown> = { ...STATIC_BUNDLED_MODULES };
|
|
91
|
+
|
|
69
92
|
const require = createRequire(import.meta.url);
|
|
70
93
|
const EXTENSION_TIMING_ENABLED = process.env.GSD_STARTUP_TIMING === "1" || process.env.PI_TIMING === "1";
|
|
71
94
|
|
|
95
|
+
/**
|
|
96
|
+
* Bundled npm packages whose subpath exports should be auto-resolved for extensions.
|
|
97
|
+
* Each package listed here will have its `exports` field read from package.json,
|
|
98
|
+
* and all subpath exports will be registered as jiti aliases (Node.js mode) so that
|
|
99
|
+
* extensions can import any standard subpath without hitting jiti's CJS double-resolve bug.
|
|
100
|
+
*/
|
|
101
|
+
const BUNDLED_PACKAGES_WITH_EXPORTS = [
|
|
102
|
+
"@modelcontextprotocol/sdk",
|
|
103
|
+
"yaml",
|
|
104
|
+
];
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* Read a package's `exports` field and return alias entries mapping
|
|
108
|
+
* specifiers (e.g. `@modelcontextprotocol/sdk/server`) to resolved file paths.
|
|
109
|
+
*
|
|
110
|
+
* Handles:
|
|
111
|
+
* - Explicit subpath exports: `./client` -> `@pkg/client`
|
|
112
|
+
* - Wildcard exports (`./*`): scans the package's dist directory for actual files
|
|
113
|
+
* - Both `.js`-suffixed and bare specifiers for each subpath
|
|
114
|
+
*/
|
|
115
|
+
function resolveSubpathExports(packageName: string): Record<string, string> {
|
|
116
|
+
const aliases: Record<string, string> = {};
|
|
117
|
+
|
|
118
|
+
let packageJsonPath: string;
|
|
119
|
+
try {
|
|
120
|
+
// Resolve the package's root directory via its package.json
|
|
121
|
+
packageJsonPath = require.resolve(`${packageName}/package.json`);
|
|
122
|
+
} catch {
|
|
123
|
+
// Package doesn't allow importing package.json via exports — find it manually
|
|
124
|
+
try {
|
|
125
|
+
const anyEntry = require.resolve(packageName);
|
|
126
|
+
// Walk up from the resolved entry to find package.json
|
|
127
|
+
let dir = path.dirname(anyEntry);
|
|
128
|
+
while (dir !== path.dirname(dir)) {
|
|
129
|
+
const candidate = path.join(dir, "package.json");
|
|
130
|
+
if (fs.existsSync(candidate)) {
|
|
131
|
+
try {
|
|
132
|
+
const pkg = JSON.parse(fs.readFileSync(candidate, "utf-8"));
|
|
133
|
+
if (pkg.name === packageName) {
|
|
134
|
+
packageJsonPath = candidate;
|
|
135
|
+
break;
|
|
136
|
+
}
|
|
137
|
+
} catch {
|
|
138
|
+
// not valid JSON, keep walking
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
dir = path.dirname(dir);
|
|
142
|
+
}
|
|
143
|
+
} catch {
|
|
144
|
+
return aliases;
|
|
145
|
+
}
|
|
146
|
+
if (!packageJsonPath!) return aliases;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
let pkg: { exports?: Record<string, unknown> };
|
|
150
|
+
try {
|
|
151
|
+
pkg = JSON.parse(fs.readFileSync(packageJsonPath, "utf-8"));
|
|
152
|
+
} catch {
|
|
153
|
+
return aliases;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
const exports = pkg.exports;
|
|
157
|
+
if (!exports || typeof exports !== "object") return aliases;
|
|
158
|
+
|
|
159
|
+
const packageDir = path.dirname(packageJsonPath);
|
|
160
|
+
|
|
161
|
+
for (const [subpath, target] of Object.entries(exports)) {
|
|
162
|
+
if (subpath === ".") continue; // Root export handled by static imports
|
|
163
|
+
|
|
164
|
+
// Handle wildcard exports like "./*"
|
|
165
|
+
if (subpath.includes("*")) {
|
|
166
|
+
resolveWildcardExports(packageName, packageDir, subpath, target, aliases);
|
|
167
|
+
continue;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
// Explicit subpath: "./client" -> "@pkg/client"
|
|
171
|
+
const specifier = `${packageName}/${subpath.replace(/^\.\//, "")}`;
|
|
172
|
+
|
|
173
|
+
try {
|
|
174
|
+
const resolved = require.resolve(specifier);
|
|
175
|
+
aliases[specifier] = resolved;
|
|
176
|
+
|
|
177
|
+
// Add .js-suffixed variant if the specifier doesn't already end in .js
|
|
178
|
+
if (!specifier.endsWith(".js")) {
|
|
179
|
+
const jsSpecifier = `${specifier}.js`;
|
|
180
|
+
try {
|
|
181
|
+
const jsResolved = require.resolve(jsSpecifier);
|
|
182
|
+
aliases[jsSpecifier] = jsResolved;
|
|
183
|
+
} catch {
|
|
184
|
+
// .js variant doesn't resolve — that's fine
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
// Add bare variant (without .js) if it ends in .js
|
|
189
|
+
if (specifier.endsWith(".js")) {
|
|
190
|
+
const bareSpecifier = specifier.slice(0, -3);
|
|
191
|
+
try {
|
|
192
|
+
const bareResolved = require.resolve(bareSpecifier);
|
|
193
|
+
aliases[bareSpecifier] = bareResolved;
|
|
194
|
+
} catch {
|
|
195
|
+
// bare variant doesn't resolve — that's fine
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
} catch {
|
|
199
|
+
// Subpath doesn't resolve — skip it
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
return aliases;
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
/**
|
|
207
|
+
* Resolve wildcard export patterns (e.g. `./*`) by scanning the package's
|
|
208
|
+
* file structure to find all matching files and generate alias entries.
|
|
209
|
+
*/
|
|
210
|
+
function resolveWildcardExports(
|
|
211
|
+
packageName: string,
|
|
212
|
+
packageDir: string,
|
|
213
|
+
subpathPattern: string,
|
|
214
|
+
target: unknown,
|
|
215
|
+
aliases: Record<string, string>,
|
|
216
|
+
): void {
|
|
217
|
+
// Extract the target directory pattern from the export target
|
|
218
|
+
// e.g. { "require": "./dist/cjs/*" } -> "dist/cjs"
|
|
219
|
+
let targetDir: string | null = null;
|
|
220
|
+
|
|
221
|
+
if (typeof target === "string") {
|
|
222
|
+
targetDir = target.replace(/\/\*$/, "").replace(/^\.\//, "");
|
|
223
|
+
} else if (target && typeof target === "object") {
|
|
224
|
+
const targetObj = target as Record<string, unknown>;
|
|
225
|
+
// Prefer "require" for CJS compatibility with jiti, fall back to "import"
|
|
226
|
+
const resolved = targetObj.require ?? targetObj.import ?? targetObj.default;
|
|
227
|
+
if (typeof resolved === "string") {
|
|
228
|
+
targetDir = resolved.replace(/\/\*$/, "").replace(/^\.\//, "");
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
if (!targetDir) return;
|
|
233
|
+
|
|
234
|
+
const fullTargetDir = path.join(packageDir, targetDir);
|
|
235
|
+
if (!fs.existsSync(fullTargetDir)) return;
|
|
236
|
+
|
|
237
|
+
// Scan for .js files and generate specifiers
|
|
238
|
+
const subpathPrefix = subpathPattern.replace(/\/?\*$/, "").replace(/^\.\//, "");
|
|
239
|
+
scanDirForExports(packageName, fullTargetDir, subpathPrefix, aliases);
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
/**
|
|
243
|
+
* Recursively scan a directory for .js files and register them as aliases.
|
|
244
|
+
*/
|
|
245
|
+
function scanDirForExports(
|
|
246
|
+
packageName: string,
|
|
247
|
+
dir: string,
|
|
248
|
+
relativePath: string,
|
|
249
|
+
aliases: Record<string, string>,
|
|
250
|
+
): void {
|
|
251
|
+
let entries: fs.Dirent[];
|
|
252
|
+
try {
|
|
253
|
+
entries = fs.readdirSync(dir, { withFileTypes: true });
|
|
254
|
+
} catch {
|
|
255
|
+
return;
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
for (const entry of entries) {
|
|
259
|
+
const entryRelative = relativePath ? `${relativePath}/${entry.name}` : entry.name;
|
|
260
|
+
|
|
261
|
+
if (entry.isDirectory()) {
|
|
262
|
+
// Skip examples/test directories — extensions don't need them
|
|
263
|
+
if (entry.name === "examples" || entry.name === "__tests__" || entry.name === "test") continue;
|
|
264
|
+
scanDirForExports(packageName, path.join(dir, entry.name), entryRelative, aliases);
|
|
265
|
+
} else if (entry.name.endsWith(".js") && !entry.name.endsWith(".d.js")) {
|
|
266
|
+
const filePath = path.join(dir, entry.name);
|
|
267
|
+
const specifier = `${packageName}/${entryRelative}`;
|
|
268
|
+
// Only add if not already covered by an explicit export
|
|
269
|
+
if (!(specifier in aliases)) {
|
|
270
|
+
aliases[specifier] = filePath;
|
|
271
|
+
}
|
|
272
|
+
// Also add bare (no .js) variant
|
|
273
|
+
const bareSpecifier = specifier.replace(/\.js$/, "");
|
|
274
|
+
if (!(bareSpecifier in aliases)) {
|
|
275
|
+
aliases[bareSpecifier] = filePath;
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
|
|
72
281
|
function logExtensionTiming(extensionPath: string, ms: number, outcome: "loaded" | "failed"): void {
|
|
73
282
|
if (!EXTENSION_TIMING_ENABLED) return;
|
|
74
283
|
console.error(`[startup] extension ${outcome}: ${extensionPath} (${ms}ms)`);
|
|
@@ -100,7 +309,19 @@ function getAliases(): Record<string, string> {
|
|
|
100
309
|
return fileURLToPath(import.meta.resolve(specifier));
|
|
101
310
|
};
|
|
102
311
|
|
|
312
|
+
// Auto-discover subpath exports from bundled npm packages.
|
|
313
|
+
// This ensures extensions can import any standard subpath (e.g. @modelcontextprotocol/sdk/server)
|
|
314
|
+
// without hitting jiti's CJS double-resolve bug.
|
|
315
|
+
const autoDiscovered: Record<string, string> = {};
|
|
316
|
+
for (const packageName of BUNDLED_PACKAGES_WITH_EXPORTS) {
|
|
317
|
+
const subpathAliases = resolveSubpathExports(packageName);
|
|
318
|
+
Object.assign(autoDiscovered, subpathAliases);
|
|
319
|
+
}
|
|
320
|
+
|
|
103
321
|
_aliases = {
|
|
322
|
+
// Auto-discovered subpath exports (lowest priority — overridden by manual entries below)
|
|
323
|
+
...autoDiscovered,
|
|
324
|
+
// Manual entries for workspace packages and packages needing special resolution
|
|
104
325
|
"@gsd/pi-coding-agent": packageIndex,
|
|
105
326
|
"@gsd/pi-agent-core": resolveWorkspaceOrImport("agent/dist/index.js", "@gsd/pi-agent-core"),
|
|
106
327
|
"@gsd/pi-tui": resolveWorkspaceOrImport("tui/dist/index.js", "@gsd/pi-tui"),
|
|
@@ -108,11 +329,6 @@ function getAliases(): Record<string, string> {
|
|
|
108
329
|
"@gsd/pi-ai/oauth": resolveWorkspaceOrImport("ai/dist/oauth.js", "@gsd/pi-ai/oauth"),
|
|
109
330
|
"@sinclair/typebox": typeboxRoot,
|
|
110
331
|
"yaml": yamlRoot,
|
|
111
|
-
"@modelcontextprotocol/sdk/client": require.resolve("@modelcontextprotocol/sdk/client"),
|
|
112
|
-
"@modelcontextprotocol/sdk/client/stdio": require.resolve("@modelcontextprotocol/sdk/client/stdio.js"),
|
|
113
|
-
"@modelcontextprotocol/sdk/client/stdio.js": require.resolve("@modelcontextprotocol/sdk/client/stdio.js"),
|
|
114
|
-
"@modelcontextprotocol/sdk/client/streamableHttp": require.resolve("@modelcontextprotocol/sdk/client/streamableHttp.js"),
|
|
115
|
-
"@modelcontextprotocol/sdk/client/streamableHttp.js": require.resolve("@modelcontextprotocol/sdk/client/streamableHttp.js"),
|
|
116
332
|
// Aliases for external PI ecosystem packages that import from the original scope
|
|
117
333
|
"@mariozechner/pi-coding-agent": packageIndex,
|
|
118
334
|
"@mariozechner/pi-agent-core": resolveWorkspaceOrImport("agent/dist/index.js", "@gsd/pi-agent-core"),
|
|
@@ -14,6 +14,7 @@ import type { ModelRegistry } from "./model-registry.js";
|
|
|
14
14
|
const defaultModelPerProvider: Record<KnownProvider, string> = {
|
|
15
15
|
"amazon-bedrock": "us.anthropic.claude-opus-4-6-v1",
|
|
16
16
|
anthropic: "claude-opus-4-6[1m]",
|
|
17
|
+
"anthropic-vertex": "claude-sonnet-4-6",
|
|
17
18
|
openai: "gpt-5.4",
|
|
18
19
|
"azure-openai-responses": "gpt-5.2",
|
|
19
20
|
"openai-codex": "gpt-5.4",
|
|
@@ -414,7 +414,13 @@ function resolveExtensionEntries(dir: string): string[] | null {
|
|
|
414
414
|
const packageJsonPath = join(dir, "package.json");
|
|
415
415
|
if (existsSync(packageJsonPath)) {
|
|
416
416
|
const manifest = readPiManifestFile(packageJsonPath);
|
|
417
|
-
if (manifest
|
|
417
|
+
if (manifest) {
|
|
418
|
+
// When a pi manifest exists, it is authoritative — don't fall through
|
|
419
|
+
// to index.ts/index.js auto-detection. This allows library directories
|
|
420
|
+
// (like cmux) to opt out by declaring "pi": {} with no extensions.
|
|
421
|
+
if (!manifest.extensions?.length) {
|
|
422
|
+
return null;
|
|
423
|
+
}
|
|
418
424
|
const entries: string[] = [];
|
|
419
425
|
for (const extPath of manifest.extensions) {
|
|
420
426
|
const resolvedExtPath = resolve(dir, extPath);
|
|
@@ -422,9 +428,7 @@ function resolveExtensionEntries(dir: string): string[] | null {
|
|
|
422
428
|
entries.push(resolvedExtPath);
|
|
423
429
|
}
|
|
424
430
|
}
|
|
425
|
-
|
|
426
|
-
return entries;
|
|
427
|
-
}
|
|
431
|
+
return entries.length > 0 ? entries : null;
|
|
428
432
|
}
|
|
429
433
|
}
|
|
430
434
|
|
package/pkg/package.json
CHANGED
|
@@ -289,10 +289,17 @@ export class CmuxClient {
|
|
|
289
289
|
}
|
|
290
290
|
|
|
291
291
|
async createSplit(direction: "right" | "down" | "left" | "up"): Promise<string | null> {
|
|
292
|
+
return this.createSplitFrom(this.config.surfaceId, direction);
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
async createSplitFrom(
|
|
296
|
+
sourceSurfaceId: string | undefined,
|
|
297
|
+
direction: "right" | "down" | "left" | "up",
|
|
298
|
+
): Promise<string | null> {
|
|
292
299
|
if (!this.config.splits) return null;
|
|
293
300
|
const before = new Set(await this.listSurfaceIds());
|
|
294
301
|
const args = ["new-split", direction];
|
|
295
|
-
const scopedArgs = this.appendSurface(this.appendWorkspace(args),
|
|
302
|
+
const scopedArgs = this.appendSurface(this.appendWorkspace(args), sourceSurfaceId);
|
|
296
303
|
await this.runAsync(scopedArgs);
|
|
297
304
|
const after = await this.listSurfaceIds();
|
|
298
305
|
for (const id of after) {
|
|
@@ -301,6 +308,55 @@ export class CmuxClient {
|
|
|
301
308
|
return null;
|
|
302
309
|
}
|
|
303
310
|
|
|
311
|
+
/**
|
|
312
|
+
* Create a grid of surfaces for parallel agent execution.
|
|
313
|
+
*
|
|
314
|
+
* Layout strategy (gsd stays in the original surface):
|
|
315
|
+
* 1 agent: [gsd | A]
|
|
316
|
+
* 2 agents: [gsd | A]
|
|
317
|
+
* [ | B]
|
|
318
|
+
* 3 agents: [gsd | A]
|
|
319
|
+
* [ C | B]
|
|
320
|
+
* 4 agents: [gsd | A]
|
|
321
|
+
* [ C | B] (D splits from B downward)
|
|
322
|
+
* [ | D]
|
|
323
|
+
*
|
|
324
|
+
* Returns surface IDs in order, or empty array on failure.
|
|
325
|
+
*/
|
|
326
|
+
async createGridLayout(count: number): Promise<string[]> {
|
|
327
|
+
if (!this.config.splits || count <= 0) return [];
|
|
328
|
+
const surfaces: string[] = [];
|
|
329
|
+
|
|
330
|
+
// First split: create right column from the gsd surface
|
|
331
|
+
const rightCol = await this.createSplitFrom(this.config.surfaceId, "right");
|
|
332
|
+
if (!rightCol) return [];
|
|
333
|
+
surfaces.push(rightCol);
|
|
334
|
+
if (count === 1) return surfaces;
|
|
335
|
+
|
|
336
|
+
// Second split: split right column down → bottom-right
|
|
337
|
+
const bottomRight = await this.createSplitFrom(rightCol, "down");
|
|
338
|
+
if (!bottomRight) return surfaces;
|
|
339
|
+
surfaces.push(bottomRight);
|
|
340
|
+
if (count === 2) return surfaces;
|
|
341
|
+
|
|
342
|
+
// Third split: split gsd surface down → bottom-left
|
|
343
|
+
const bottomLeft = await this.createSplitFrom(this.config.surfaceId, "down");
|
|
344
|
+
if (!bottomLeft) return surfaces;
|
|
345
|
+
surfaces.push(bottomLeft);
|
|
346
|
+
if (count === 3) return surfaces;
|
|
347
|
+
|
|
348
|
+
// Fourth+: split subsequent surfaces down from the last created
|
|
349
|
+
let lastSurface = bottomRight;
|
|
350
|
+
for (let i = 3; i < count; i++) {
|
|
351
|
+
const next = await this.createSplitFrom(lastSurface, "down");
|
|
352
|
+
if (!next) break;
|
|
353
|
+
surfaces.push(next);
|
|
354
|
+
lastSurface = next;
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
return surfaces;
|
|
358
|
+
}
|
|
359
|
+
|
|
304
360
|
async sendSurface(surfaceId: string, text: string): Promise<boolean> {
|
|
305
361
|
const payload = text.endsWith("\n") ? text : `${text}\n`;
|
|
306
362
|
const stdout = await this.runAsync(["send-surface", "--surface", surfaceId, payload]);
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
// GSD Extension — Environment variable utilities
|
|
2
|
+
// Copyright (c) 2026 Jeremy McSpadden <jeremy@fluxlabs.net>
|
|
3
|
+
//
|
|
4
|
+
// Pure utility for checking existing env keys in .env files and process.env.
|
|
5
|
+
// Extracted from get-secrets-from-user.ts to avoid pulling in @gsd/pi-tui
|
|
6
|
+
// when only env-checking is needed (e.g. from files.ts during report generation).
|
|
7
|
+
|
|
8
|
+
import { readFile } from "node:fs/promises";
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Check which keys already exist in a .env file or process.env.
|
|
12
|
+
* Returns the subset of `keys` that are already set.
|
|
13
|
+
*/
|
|
14
|
+
export async function checkExistingEnvKeys(keys: string[], envFilePath: string): Promise<string[]> {
|
|
15
|
+
let fileContent = "";
|
|
16
|
+
try {
|
|
17
|
+
fileContent = await readFile(envFilePath, "utf8");
|
|
18
|
+
} catch {
|
|
19
|
+
// ENOENT or other read error — proceed with empty content
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
const existing: string[] = [];
|
|
23
|
+
for (const key of keys) {
|
|
24
|
+
const escaped = key.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
25
|
+
const regex = new RegExp(`^${escaped}\\s*=`, "m");
|
|
26
|
+
if (regex.test(fileContent) || key in process.env) {
|
|
27
|
+
existing.push(key);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
return existing;
|
|
31
|
+
}
|
|
@@ -67,30 +67,11 @@ async function writeEnvKey(filePath: string, key: string, value: string): Promis
|
|
|
67
67
|
|
|
68
68
|
// ─── Exported utilities ───────────────────────────────────────────────────────
|
|
69
69
|
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
*/
|
|
76
|
-
export async function checkExistingEnvKeys(keys: string[], envFilePath: string): Promise<string[]> {
|
|
77
|
-
let fileContent = "";
|
|
78
|
-
try {
|
|
79
|
-
fileContent = await readFile(envFilePath, "utf8");
|
|
80
|
-
} catch {
|
|
81
|
-
// ENOENT or other read error — proceed with empty content
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
const existing: string[] = [];
|
|
85
|
-
for (const key of keys) {
|
|
86
|
-
const escaped = key.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
87
|
-
const regex = new RegExp(`^${escaped}\\s*=`, "m");
|
|
88
|
-
if (regex.test(fileContent) || key in process.env) {
|
|
89
|
-
existing.push(key);
|
|
90
|
-
}
|
|
91
|
-
}
|
|
92
|
-
return existing;
|
|
93
|
-
}
|
|
70
|
+
// Re-export from env-utils.ts so existing consumers still work.
|
|
71
|
+
// The implementation lives in env-utils.ts to avoid pulling @gsd/pi-tui
|
|
72
|
+
// into modules that only need env-checking (e.g. files.ts during reports).
|
|
73
|
+
import { checkExistingEnvKeys } from "./env-utils.js";
|
|
74
|
+
export { checkExistingEnvKeys };
|
|
94
75
|
|
|
95
76
|
/**
|
|
96
77
|
* Detect the write destination based on project files in basePath.
|