@cjhyy/code-shell-core 0.6.0-rc.9 → 0.7.0
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/THIRD_PARTY_NOTICES.md +206 -0
- package/dist/automation/scheduler.d.ts +13 -7
- package/dist/automation/scheduler.js +116 -37
- package/dist/capability-control/service.d.ts +2 -0
- package/dist/capability-control/service.js +4 -2
- package/dist/cc-orchestrator/agent-adapter.d.ts +4 -0
- package/dist/cc-orchestrator/agent-adapter.js +11 -1
- package/dist/cc-orchestrator/codex-session-history.d.ts +14 -1
- package/dist/cc-orchestrator/codex-session-history.js +65 -5
- package/dist/cc-orchestrator/cwd-normalize.d.ts +2 -0
- package/dist/cc-orchestrator/cwd-normalize.js +19 -0
- package/dist/cc-orchestrator/external-agent-bindings.d.ts +27 -0
- package/dist/cc-orchestrator/external-agent-bindings.js +150 -0
- package/dist/cc-orchestrator/external-agent-changes.js +22 -5
- package/dist/cc-orchestrator/external-agent-driver.d.ts +1 -0
- package/dist/cc-orchestrator/external-agent-driver.js +265 -50
- package/dist/cc-orchestrator/external-agent-session-store.d.ts +23 -0
- package/dist/cc-orchestrator/external-agent-session-store.js +146 -0
- package/dist/cc-orchestrator/session-history.d.ts +35 -0
- package/dist/cc-orchestrator/session-history.js +98 -15
- package/dist/cli/agent-server-stdio.js +9 -2
- package/dist/context/compaction.d.ts +8 -1
- package/dist/context/compaction.js +49 -4
- package/dist/context/manager.d.ts +16 -2
- package/dist/context/manager.js +103 -19
- package/dist/credentials/access.d.ts +57 -0
- package/dist/credentials/access.js +185 -0
- package/dist/credentials/index.d.ts +3 -1
- package/dist/credentials/index.js +2 -0
- package/dist/credentials/inject-credential-tool.d.ts +3 -1
- package/dist/credentials/inject-credential-tool.js +30 -11
- package/dist/credentials/oauth.d.ts +20 -0
- package/dist/credentials/oauth.js +114 -0
- package/dist/credentials/store.d.ts +1 -0
- package/dist/credentials/store.js +3 -1
- package/dist/credentials/types.d.ts +49 -3
- package/dist/credentials/use-credential-tool.d.ts +9 -1
- package/dist/credentials/use-credential-tool.js +58 -45
- package/dist/engine/engine.d.ts +23 -3
- package/dist/engine/engine.js +380 -255
- package/dist/engine/goal.d.ts +17 -0
- package/dist/engine/goal.js +16 -6
- package/dist/engine/image-policy.d.ts +6 -0
- package/dist/engine/image-policy.js +17 -6
- package/dist/engine/input-attachments.d.ts +13 -0
- package/dist/engine/input-attachments.js +398 -0
- package/dist/engine/model-facade.d.ts +5 -2
- package/dist/engine/model-facade.js +4 -4
- package/dist/engine/parse-task.d.ts +10 -0
- package/dist/engine/parse-task.js +5 -0
- package/dist/engine/run-image-input.d.ts +22 -0
- package/dist/engine/run-image-input.js +195 -0
- package/dist/engine/steer-queue.d.ts +3 -1
- package/dist/engine/steer-queue.js +10 -2
- package/dist/engine/streaming-tool-queue.d.ts +11 -7
- package/dist/engine/streaming-tool-queue.js +11 -7
- package/dist/engine/turn-loop.d.ts +37 -2
- package/dist/engine/turn-loop.js +228 -43
- package/dist/engine/types.d.ts +8 -0
- package/dist/git/worktree/crud.d.ts +69 -0
- package/dist/git/worktree/crud.js +206 -0
- package/dist/git/worktree/diff.d.ts +14 -0
- package/dist/git/worktree/diff.js +82 -0
- package/dist/git/worktree/git-exec.d.ts +7 -0
- package/dist/git/worktree/git-exec.js +51 -0
- package/dist/git/worktree/index.d.ts +5 -0
- package/dist/git/worktree/index.js +5 -0
- package/dist/git/worktree/query.d.ts +42 -0
- package/dist/git/worktree/query.js +121 -0
- package/dist/git/worktree/slug.d.ts +11 -0
- package/dist/git/worktree/slug.js +58 -0
- package/dist/git/worktree.d.ts +1 -84
- package/dist/git/worktree.js +5 -230
- package/dist/hooks/goal-stop-hook.d.ts +33 -1
- package/dist/hooks/goal-stop-hook.js +202 -34
- package/dist/index.d.ts +31 -28
- package/dist/index.js +27 -25
- package/dist/logging/logger.js +6 -6
- package/dist/logging/sanitize-messages.d.ts +10 -2
- package/dist/logging/sanitize-messages.js +21 -6
- package/dist/plugins/installer/checkUpdate.d.ts +4 -1
- package/dist/plugins/installer/checkUpdate.js +4 -2
- package/dist/plugins/installer/install.js +2 -0
- package/dist/plugins/installer/installFromSource.js +9 -1
- package/dist/plugins/installer/parseSource.d.ts +4 -1
- package/dist/plugins/installer/parseSource.js +28 -10
- package/dist/plugins/installer/sourcePath.d.ts +9 -0
- package/dist/plugins/installer/sourcePath.js +50 -0
- package/dist/plugins/installer/update.d.ts +4 -1
- package/dist/plugins/installer/update.js +5 -3
- package/dist/plugins/parseMarketplaceInput.d.ts +4 -1
- package/dist/plugins/parseMarketplaceInput.js +4 -3
- package/dist/plugins/pluginInstaller.js +24 -22
- package/dist/preset/index.d.ts +1 -0
- package/dist/preset/index.js +30 -13
- package/dist/prompt/sections/base.md +1 -1
- package/dist/protocol/chat-session-manager.d.ts +2 -0
- package/dist/protocol/chat-session-manager.js +38 -2
- package/dist/protocol/chat-session.d.ts +3 -0
- package/dist/protocol/chat-session.js +1 -0
- package/dist/protocol/client.d.ts +9 -4
- package/dist/protocol/client.js +18 -1
- package/dist/protocol/server.d.ts +30 -0
- package/dist/protocol/server.js +247 -47
- package/dist/protocol/types.d.ts +49 -0
- package/dist/protocol/types.js +6 -0
- package/dist/run/FileRunStore.js +10 -1
- package/dist/run/Heartbeat.js +12 -0
- package/dist/run/RunApprovalBackend.d.ts +3 -0
- package/dist/run/RunApprovalBackend.js +41 -6
- package/dist/run/RunLock.js +2 -0
- package/dist/run/RunManager.d.ts +2 -0
- package/dist/run/RunManager.js +64 -24
- package/dist/run/ids.d.ts +2 -0
- package/dist/run/ids.js +23 -0
- package/dist/runtime/background-shell.d.ts +1 -0
- package/dist/runtime/background-shell.js +23 -13
- package/dist/runtime/spawn-common.js +10 -0
- package/dist/services/auto-dream.d.ts +15 -4
- package/dist/services/auto-dream.js +20 -20
- package/dist/services/dream-consolidation.d.ts +2 -3
- package/dist/services/dream-consolidation.js +65 -15
- package/dist/services/extract-memories.d.ts +14 -5
- package/dist/services/extract-memories.js +20 -3
- package/dist/services/global-dream-promotion.d.ts +23 -0
- package/dist/services/global-dream-promotion.js +112 -0
- package/dist/services/memory-orchestrator.js +347 -34
- package/dist/session/memory.d.ts +61 -18
- package/dist/session/memory.js +342 -79
- package/dist/session/session-manager.d.ts +35 -1
- package/dist/session/session-manager.js +224 -4
- package/dist/session/transcript.d.ts +1 -1
- package/dist/session/transcript.js +17 -5
- package/dist/settings/manager.d.ts +1 -0
- package/dist/settings/manager.js +87 -37
- package/dist/settings/schema-export.d.ts +2 -3
- package/dist/settings/schema-export.js +2 -3
- package/dist/settings/schema.d.ts +21 -0
- package/dist/settings/schema.js +12 -0
- package/dist/skills/scanner.d.ts +3 -2
- package/dist/skills/scanner.js +12 -9
- package/dist/tool-system/builtin/agent-notifications.d.ts +11 -4
- package/dist/tool-system/builtin/agent-notifications.js +19 -7
- package/dist/tool-system/builtin/background-jobs.d.ts +35 -6
- package/dist/tool-system/builtin/background-jobs.js +116 -7
- package/dist/tool-system/builtin/background-work.d.ts +17 -18
- package/dist/tool-system/builtin/background-work.js +51 -5
- package/dist/tool-system/builtin/config.d.ts +2 -1
- package/dist/tool-system/builtin/config.js +16 -11
- package/dist/tool-system/builtin/cron-list.definition.d.ts +3 -0
- package/dist/tool-system/builtin/cron-list.definition.js +6 -0
- package/dist/tool-system/builtin/cron.d.ts +1 -2
- package/dist/tool-system/builtin/cron.js +9 -7
- package/dist/tool-system/builtin/drive-claude-code.d.ts +23 -2
- package/dist/tool-system/builtin/drive-claude-code.js +589 -48
- package/dist/tool-system/builtin/edit.js +5 -2
- package/dist/tool-system/builtin/generate-video.d.ts +1 -0
- package/dist/tool-system/builtin/generate-video.js +13 -4
- package/dist/tool-system/builtin/index.d.ts +8 -3
- package/dist/tool-system/builtin/index.js +50 -22
- package/dist/tool-system/builtin/lsp.d.ts +2 -1
- package/dist/tool-system/builtin/lsp.js +6 -3
- package/dist/tool-system/builtin/memory.js +40 -8
- package/dist/tool-system/builtin/notebook-edit.js +5 -2
- package/dist/tool-system/builtin/powershell.d.ts +5 -2
- package/dist/tool-system/builtin/powershell.js +11 -7
- package/dist/tool-system/builtin/read.js +118 -6
- package/dist/tool-system/builtin/sleep.d.ts +1 -2
- package/dist/tool-system/builtin/sleep.definition.d.ts +8 -0
- package/dist/tool-system/builtin/sleep.definition.js +28 -0
- package/dist/tool-system/builtin/sleep.js +1 -22
- package/dist/tool-system/builtin/view-image.d.ts +2 -2
- package/dist/tool-system/builtin/view-image.js +109 -19
- package/dist/tool-system/builtin/worktree.d.ts +4 -4
- package/dist/tool-system/builtin/worktree.js +297 -74
- package/dist/tool-system/builtin/write.js +5 -3
- package/dist/tool-system/context.d.ts +41 -1
- package/dist/tool-system/executor.d.ts +1 -5
- package/dist/tool-system/executor.js +94 -115
- package/dist/tool-system/mcp-manager.d.ts +31 -6
- package/dist/tool-system/mcp-manager.js +193 -78
- package/dist/tool-system/path-policy.d.ts +2 -0
- package/dist/tool-system/path-policy.js +41 -12
- package/dist/tool-system/permission.d.ts +28 -7
- package/dist/tool-system/permission.js +130 -49
- package/dist/tool-system/registry.js +11 -4
- package/dist/tool-system/tool-result-redaction.d.ts +7 -0
- package/dist/tool-system/tool-result-redaction.js +48 -0
- package/dist/tool-system/workspace-bridge.d.ts +11 -0
- package/dist/tool-system/workspace-bridge.js +1 -0
- package/dist/types.d.ts +78 -11
- package/dist/utils/toolDisplay.js +1 -1
- package/package.json +4 -3
package/dist/index.js
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Public API exports.
|
|
5
5
|
*/
|
|
6
|
-
export const VERSION = "0.
|
|
6
|
+
export const VERSION = "0.7.0";
|
|
7
7
|
// ─── Exceptions ──────────────────────────────────────────────────
|
|
8
8
|
export { FrameworkError, LLMError, LLMRateLimitError, ContextLimitError, ToolError, ToolNotFoundError, ToolExecutionError, ToolTimeoutError, PermissionDeniedError, SessionError, TranscriptError, ConfigError, SandboxUnavailableError, } from "./exceptions.js";
|
|
9
9
|
// ─── Engine (primary API) ────────────────────────────────────────
|
|
@@ -11,7 +11,7 @@ export { Engine, loadAgentDefinitionsForCwd } from "./engine/engine.js";
|
|
|
11
11
|
export { resolveLLMConfigForTag } from "./engine/resolve-llm-config.js";
|
|
12
12
|
export { resolveAuxKey } from "./engine/aux-key.js";
|
|
13
13
|
export { parseAgentDefinition, serializeAgentDefinition, } from "./agent/agent-definition.js";
|
|
14
|
-
export { AgentDefinitionRegistry
|
|
14
|
+
export { AgentDefinitionRegistry } from "./agent/agent-definition-registry.js";
|
|
15
15
|
export { EngineRuntime } from "./engine/runtime.js";
|
|
16
16
|
export { ChatSessionManager } from "./protocol/chat-session-manager.js";
|
|
17
17
|
// ─── LLM ─────────────────────────────────────────────────────────
|
|
@@ -24,7 +24,7 @@ export { modelEntriesFromConnections } from "./engine/model-connections-pool.js"
|
|
|
24
24
|
// ─── Tools ───────────────────────────────────────────────────────
|
|
25
25
|
export { ToolRegistry } from "./tool-system/registry.js";
|
|
26
26
|
export { ToolExecutor } from "./tool-system/executor.js";
|
|
27
|
-
export { PermissionClassifier, HeadlessApprovalBackend, AutoApprovalBackend } from "./tool-system/permission.js";
|
|
27
|
+
export { PermissionClassifier, HeadlessApprovalBackend, AutoApprovalBackend, } from "./tool-system/permission.js";
|
|
28
28
|
export { BUILTIN_TOOLS } from "./tool-system/builtin/index.js";
|
|
29
29
|
export { makeUpdateAutomationMemoryTool } from "./tool-system/builtin/update-automation-memory.js";
|
|
30
30
|
export { MCPManager, buildHttpHeaders, buildStdioEnv } from "./tool-system/mcp-manager.js";
|
|
@@ -34,16 +34,17 @@ export { wrapHookMessages } from "./hooks/inject.js";
|
|
|
34
34
|
// ─── Protocol (client/server + transports) ──────────────────────
|
|
35
35
|
export { AgentServer } from "./protocol/server.js";
|
|
36
36
|
export { AgentClient } from "./protocol/client.js";
|
|
37
|
-
export { createInProcessTransport, StdioTransport
|
|
38
|
-
export { SocketTransport, listenTcp
|
|
37
|
+
export { createInProcessTransport, StdioTransport } from "./protocol/transport.js";
|
|
38
|
+
export { SocketTransport, listenTcp } from "./protocol/tcp-transport.js";
|
|
39
39
|
// Recommended public factories — see protocol/factories.ts for the
|
|
40
40
|
// stable construction contract referenced by standard §7.
|
|
41
41
|
export { createServer, createClient, } from "./protocol/factories.js";
|
|
42
|
-
export { Methods, ErrorCodes
|
|
42
|
+
export { Methods, ErrorCodes } from "./protocol/types.js";
|
|
43
43
|
// ─── Session ─────────────────────────────────────────────────────
|
|
44
44
|
export { Transcript } from "./session/transcript.js";
|
|
45
45
|
export { SessionManager } from "./session/session-manager.js";
|
|
46
46
|
export { FileHistory } from "./session/file-history.js";
|
|
47
|
+
export { createWorktree, currentBranch, DEFAULT_WORKTREE_BRANCH_PREFIX, getWorktreeDiff, isManagedWorktreeBranch, isValidWorktreeBranchPrefix, findMainWorktreeRoot, listWorktrees, listWorktreesFast, normalizeWorktreeBranchPrefix, removeWorktree, validateWorktreeSlug, worktreeHasUncommittedOrAheadChanges, worktreeHasUncommittedChanges, } from "./git/worktree.js";
|
|
47
48
|
export { latestUndoTarget, earliestSnapshotsPerFile, latestTurnUndoTargets, latestRedoTargets, } from "./session/undo-target.js";
|
|
48
49
|
export { diffLines, renderDiffPreview } from "./session/simple-diff.js";
|
|
49
50
|
export { MemoryManager } from "./session/memory.js";
|
|
@@ -54,7 +55,7 @@ export { SectionCache } from "./prompt/section-cache.js";
|
|
|
54
55
|
export { scanInstructions, combineInstructions } from "./prompt/instruction-scanner.js";
|
|
55
56
|
// ─── Presets ─────────────────────────────────────────────────────
|
|
56
57
|
export { BUILTIN_AGENT_PRESETS, DEFAULT_AGENT_PRESET, DEFAULT_CLI_PRESET, resolveAgentPreset, resolveBuiltinToolNames, buildPresetSystemPrompt, registerPreset, listPresetNames, } from "./preset/index.js";
|
|
57
|
-
export { loadSection, loadSections, availableSections, registerSection } from "./prompt/section-loader.js";
|
|
58
|
+
export { loadSection, loadSections, availableSections, registerSection, } from "./prompt/section-loader.js";
|
|
58
59
|
// ─── Context ─────────────────────────────────────────────────────
|
|
59
60
|
export { ContextManager } from "./context/manager.js";
|
|
60
61
|
export { estimateTokens, microcompact, windowCompact, truncateToolResult, buildSummarizationPrompt, applySummaryCompaction, COMPACTABLE_TOOL_NAMES, } from "./context/compaction.js";
|
|
@@ -71,7 +72,7 @@ export { installPluginFromSource } from "./plugins/installer/installFromSource.j
|
|
|
71
72
|
export { installLocalPlugin, installPluginFromArchive, } from "./plugins/installer/installFromArchive.js";
|
|
72
73
|
export { parseSource } from "./plugins/installer/parseSource.js";
|
|
73
74
|
export { detectPluginFormat } from "./plugins/installer/detectFormat.js";
|
|
74
|
-
export { CodexPluginManifest, CSMeta, PluginInstallError
|
|
75
|
+
export { CodexPluginManifest, CSMeta, PluginInstallError } from "./plugins/installer/types.js";
|
|
75
76
|
export { mergePluginMcpServers } from "./plugins/installer/loadPluginMcp.js";
|
|
76
77
|
export { listPluginHooks, pluginHookKey } from "./plugins/loadPluginHooks.js";
|
|
77
78
|
export { describePluginContent } from "./plugins/pluginContent.js";
|
|
@@ -85,14 +86,14 @@ export { checkPluginUpdate } from "./plugins/installer/checkUpdate.js";
|
|
|
85
86
|
export { Arena } from "./arena/arena.js";
|
|
86
87
|
export { MODEL_PRESETS, getMaxOutputTokens } from "./arena/model-presets.js";
|
|
87
88
|
export { detectArenaMode } from "./arena/detect-mode.js";
|
|
88
|
-
export { getStrategy, getStrategyForPlan, ReviewStrategy, DiscussionStrategy, PlanningStrategy } from "./arena/strategies/index.js";
|
|
89
|
+
export { getStrategy, getStrategyForPlan, ReviewStrategy, DiscussionStrategy, PlanningStrategy, } from "./arena/strategies/index.js";
|
|
89
90
|
export { planArena } from "./arena/planner.js";
|
|
90
91
|
export { collectEvidence } from "./arena/providers/index.js";
|
|
91
92
|
export { selectTools, hasTools } from "./arena/tools/selector.js";
|
|
92
93
|
export { ArenaLedger } from "./arena/ledger.js";
|
|
93
94
|
export { registerClaims, selectClaimsForReview } from "./arena/phases/claim-registry.js";
|
|
94
95
|
export { buildDigest, formatDigest } from "./arena/digest-builder.js";
|
|
95
|
-
export { transitionClaim, resolveClaimStatus, markUnderReview, applyReviewResult, markUnresolved, isTerminal, validTransitions } from "./arena/transitions.js";
|
|
96
|
+
export { transitionClaim, resolveClaimStatus, markUnderReview, applyReviewResult, markUnresolved, isTerminal, validTransitions, } from "./arena/transitions.js";
|
|
96
97
|
// ─── Arena: Iterate mode ────────────────────────────────────────
|
|
97
98
|
// Multi-model authoring loop (tournament v1 → critique-revise rounds).
|
|
98
99
|
// Use IterativeArena to produce a draft from scratch (code, PRD, design doc);
|
|
@@ -121,12 +122,12 @@ export { defineProduct, } from "./product/index.js";
|
|
|
121
122
|
// ─── Logging ─────────────────────────────────────────────────────
|
|
122
123
|
export { logger } from "./logging/logger.js";
|
|
123
124
|
// ─── Settings ────────────────────────────────────────────────────
|
|
124
|
-
export { SettingsManager } from "./settings/manager.js";
|
|
125
|
+
export { SettingsManager, userHome } from "./settings/manager.js";
|
|
125
126
|
export { migrateConfig, configVersionOf, CURRENT_CONFIG_VERSION, } from "./settings/migrate-config.js";
|
|
126
127
|
export { SettingsSchema, validateSettings } from "./settings/schema.js";
|
|
127
128
|
export { settingsJsonSchema, writeSettingsSchemaFile } from "./settings/schema-export.js";
|
|
128
129
|
export { personalizationFrom } from "./settings/personalization.js";
|
|
129
|
-
export { CredentialStore, formatNetscapeCookies, parseCookieJar, useCredentialToolDef, useCredentialToolDefFor, sweepStaleCredentialCookies, PlaintextCipher, setDefaultCredentialCipher, getDefaultCredentialCipher, } from "./credentials/index.js";
|
|
130
|
+
export { CredentialStore, buildOAuthRefreshRequest, isOAuthAccessTokenExpired, oauthCredentialStatus, parseOAuthCredentialSecret, summarizeOAuthCredentialSecret, formatNetscapeCookies, parseCookieJar, useCredentialToolDef, useCredentialToolDefFor, sweepStaleCredentialCookies, getCredentialAccess, setDefaultCredentialAccess, createIpcCredentialAccess, localCredentialAccess, credentialAccessScope, isCredentialSecretAvailable, materializeCookieSecret, PlaintextCipher, setDefaultCredentialCipher, getDefaultCredentialCipher, } from "./credentials/index.js";
|
|
130
131
|
// ─── State (runtime singletons shared with TUI) ──────────────────
|
|
131
132
|
/** @internal Shared with the in-repo TUI/desktop hosts; not stable SDK surface. */
|
|
132
133
|
export { getSessionId, switchSession, getOriginalCwd, setOriginalCwd, getProjectRoot, setProjectRoot, getCwdState, getIsInteractive, updateLastInteractionTime, flushInteractionTime, markScrollActivity, } from "./state.js";
|
|
@@ -149,7 +150,7 @@ export { startCapturingEarlyInput, stopCapturingEarlyInput, consumeEarlyInput, h
|
|
|
149
150
|
export { formatBytes, formatToolArgs, singleLine, MAX_LINE_WIDTH, TOOL_DOT_COLORS, } from "./utils/toolDisplay.js";
|
|
150
151
|
export { classifyBashLines, } from "./tool-system/builtin/bash-output-style.js";
|
|
151
152
|
export { formatDuration, formatTokens } from "./utils/format.js";
|
|
152
|
-
export { getTheme
|
|
153
|
+
export { getTheme } from "./utils/theme.js";
|
|
153
154
|
export { resolveThemeSetting } from "./utils/systemTheme.js";
|
|
154
155
|
// ─── Logging (extended) ──────────────────────────────────────────
|
|
155
156
|
/** @internal Host-lifecycle logging hooks for the in-repo TUI/desktop hosts; not stable SDK surface. */
|
|
@@ -174,7 +175,7 @@ export { buildReviewPrompt, parseDimensions, ALL_DIMENSIONS, } from "./review/re
|
|
|
174
175
|
* primary Engine/Protocol API above.
|
|
175
176
|
*/
|
|
176
177
|
export { getInteractiveApprovalBackend } from "./tool-system/permission.js";
|
|
177
|
-
export { defaultSandboxConfig
|
|
178
|
+
export { defaultSandboxConfig } from "./tool-system/sandbox/index.js";
|
|
178
179
|
export { buildNotificationMessage, buildNotificationSummary, notificationQueue, agentNotificationBus, notificationItemToStreamEvent, } from "./tool-system/builtin/agent-notifications.js";
|
|
179
180
|
// Automation — zero-env-dependency scheduling module (startAutomation facade
|
|
180
181
|
// + scheduler/store/runner). Hosts (Electron main, future CLI server) load
|
|
@@ -185,8 +186,9 @@ export * from "./cc-orchestrator/index.js";
|
|
|
185
186
|
// Quota — remaining CC/Codex subscription usage (self-contained, plugin-liftable).
|
|
186
187
|
export { checkQuota, formatQuota } from "./quota/index.js";
|
|
187
188
|
export { resolveQuotaCredentials } from "./quota/credentials.js";
|
|
188
|
-
export { asyncAgentRegistry
|
|
189
|
+
export { asyncAgentRegistry } from "./tool-system/builtin/agent-registry.js";
|
|
189
190
|
export { backgroundShellManager, BackgroundShellManager, } from "./runtime/background-shell.js";
|
|
191
|
+
export { ENV_DENY_REGEX, ENV_ALLOWLIST } from "./runtime/spawn-common.js";
|
|
190
192
|
export { getImageProvider, DEFAULT_IMAGE_MODEL, } from "./tool-system/builtin/image-providers.js";
|
|
191
193
|
// ─── Speech-to-text (voice input / 听写) ────────────────────────
|
|
192
194
|
export { transcribe, } from "./stt/transcribe.js";
|
|
@@ -200,21 +202,21 @@ export { createInProcessClient } from "./protocol/helpers.js";
|
|
|
200
202
|
export { formatArenaResult, printArenaResult, renderProgress, createProgressRenderer, } from "./arena/render/terminal.js";
|
|
201
203
|
export { formatArenaResultForSession } from "./arena/render/session.js";
|
|
202
204
|
// ─── Plugins ─────────────────────────────────────────────────────
|
|
203
|
-
export { installPlugin, uninstallPlugin, listInstalled
|
|
205
|
+
export { installPlugin, uninstallPlugin, listInstalled } from "./plugins/pluginInstaller.js";
|
|
204
206
|
export { addMarketplace, refreshMarketplace, removeMarketplace, listMarketplaces, loadMarketplace, } from "./plugins/marketplaceManager.js";
|
|
205
|
-
export { parseMarketplaceInput, deriveMarketplaceName
|
|
206
|
-
export { scanPluginCommands
|
|
207
|
+
export { parseMarketplaceInput, deriveMarketplaceName } from "./plugins/parseMarketplaceInput.js";
|
|
208
|
+
export { scanPluginCommands } from "./plugins/pluginCommandsLoader.js";
|
|
207
209
|
// ─── LLM (extended for TUI) ─────────────────────────────────────
|
|
208
210
|
/** @internal Extended LLM surface for the in-repo TUI/desktop hosts; not stable SDK surface. */
|
|
209
|
-
export { defaultCacheDir
|
|
210
|
-
export { fetchModelList
|
|
211
|
-
export { sanitizeApiKey, hasNonAsciiPrintable
|
|
212
|
-
export { PROVIDER_KINDS
|
|
213
|
-
export { capabilitiesFor
|
|
211
|
+
export { defaultCacheDir } from "./llm/model-cache.js";
|
|
212
|
+
export { fetchModelList } from "./llm/model-fetcher.js";
|
|
213
|
+
export { sanitizeApiKey, hasNonAsciiPrintable } from "./llm/api-key-sanitize.js";
|
|
214
|
+
export { PROVIDER_KINDS } from "./llm/provider-kinds.js";
|
|
215
|
+
export { capabilitiesFor } from "./llm/capabilities/index.js";
|
|
214
216
|
export { reasoningControlFor, } from "./llm/capabilities/reasoning-control.js";
|
|
215
|
-
export { REASONING_EFFORTS
|
|
217
|
+
export { REASONING_EFFORTS } from "./llm/reasoning-setting.js";
|
|
216
218
|
// ─── Data ────────────────────────────────────────────────────────
|
|
217
|
-
export { syncOpenRouterCatalog, getOpenRouterSnapshot
|
|
219
|
+
export { syncOpenRouterCatalog, getOpenRouterSnapshot } from "./data/openrouter-sync.js";
|
|
218
220
|
// ─── External agent config (Mobile Web Remote Rooms) ─────────────
|
|
219
221
|
// Resolves the externalAgents settings block (notably claudeCode.trustedWorkspaces),
|
|
220
222
|
// the source of truth for a Room's permission mode. The former /cc & /codex
|
package/dist/logging/logger.js
CHANGED
|
@@ -121,12 +121,12 @@ function resolveCategoryFilter() {
|
|
|
121
121
|
//
|
|
122
122
|
// Two mechanisms, layered:
|
|
123
123
|
//
|
|
124
|
-
// 1. `runWithSid(sid, fn)` — preferred. Engine.run
|
|
125
|
-
//
|
|
126
|
-
//
|
|
127
|
-
//
|
|
128
|
-
//
|
|
129
|
-
// global would.
|
|
124
|
+
// 1. `runWithSid(sid, fn)` — preferred. Once Engine.run has resolved the
|
|
125
|
+
// authoritative sid, its session-bound execution body runs in this
|
|
126
|
+
// AsyncLocalStorage scope, so every log line emitted inside the (possibly
|
|
127
|
+
// deeply async) call tree picks up the right sid. Concurrent parent + child
|
|
128
|
+
// Engines coexist because each `await` boundary preserves the ALS context —
|
|
129
|
+
// they don't trample each other like a single module global would.
|
|
130
130
|
//
|
|
131
131
|
// 2. `_currentSidFallback` — module-level mutable, written by `setCurrentSid`.
|
|
132
132
|
// Used only as a fallback when a code path runs outside any ALS scope
|
|
@@ -21,17 +21,25 @@
|
|
|
21
21
|
* pure-text turns pay essentially nothing on the fast path.
|
|
22
22
|
*/
|
|
23
23
|
import type { Message } from "../types.js";
|
|
24
|
+
export interface SanitizeMessagesOptions {
|
|
25
|
+
/**
|
|
26
|
+
* Tool-result IDs whose model-facing plaintext must be replaced before the
|
|
27
|
+
* request is written to any recorder/log sink. The original messages still
|
|
28
|
+
* go to the provider; this option is only for diagnostic copies.
|
|
29
|
+
*/
|
|
30
|
+
sensitiveToolResultRedactions?: ReadonlyMap<string, string>;
|
|
31
|
+
}
|
|
24
32
|
/**
|
|
25
33
|
* Walk a single message's content and replace image-payload blocks with
|
|
26
34
|
* metadata stubs. Returns a new value — the input is not mutated.
|
|
27
35
|
*/
|
|
28
|
-
export declare function sanitizeContent(content: Message["content"]): Message["content"];
|
|
36
|
+
export declare function sanitizeContent(content: Message["content"], options?: SanitizeMessagesOptions): Message["content"];
|
|
29
37
|
/**
|
|
30
38
|
* Walk a {@link Message}[] array and sanitize every entry's content.
|
|
31
39
|
* Returns the *same* array reference when no message held an image (fast
|
|
32
40
|
* path for the overwhelmingly common pure-text case).
|
|
33
41
|
*/
|
|
34
|
-
export declare function sanitizeMessages(messages: readonly Message[]): Message[];
|
|
42
|
+
export declare function sanitizeMessages(messages: readonly Message[], options?: SanitizeMessagesOptions): Message[];
|
|
35
43
|
/**
|
|
36
44
|
* Recursively walk a value and return a *new* value with secret-looking
|
|
37
45
|
* fields replaced by "[redacted]". Used by the logger (so anything ending up
|
|
@@ -75,19 +75,28 @@ function sanitizeImageUrlPart(part) {
|
|
|
75
75
|
image_url: {
|
|
76
76
|
// Keep the data-URL header so reviewers can see the MIME, but strip
|
|
77
77
|
// the payload. "data:image/png;base64,<omitted, 12345 bytes>"
|
|
78
|
-
url: comma === -1
|
|
79
|
-
? url
|
|
80
|
-
: `${url.slice(0, comma + 1)}<omitted, ${payloadLen} bytes>`,
|
|
78
|
+
url: comma === -1 ? url : `${url.slice(0, comma + 1)}<omitted, ${payloadLen} bytes>`,
|
|
81
79
|
omitted: true,
|
|
82
80
|
bytes: payloadLen,
|
|
83
81
|
},
|
|
84
82
|
};
|
|
85
83
|
}
|
|
84
|
+
function getSensitiveToolResultReplacement(block, options) {
|
|
85
|
+
const redactions = options?.sensitiveToolResultRedactions;
|
|
86
|
+
if (!redactions || redactions.size === 0)
|
|
87
|
+
return undefined;
|
|
88
|
+
if (!block || typeof block !== "object")
|
|
89
|
+
return undefined;
|
|
90
|
+
const b = block;
|
|
91
|
+
if (b.type !== "tool_result" || typeof b.tool_use_id !== "string")
|
|
92
|
+
return undefined;
|
|
93
|
+
return redactions.get(b.tool_use_id);
|
|
94
|
+
}
|
|
86
95
|
/**
|
|
87
96
|
* Walk a single message's content and replace image-payload blocks with
|
|
88
97
|
* metadata stubs. Returns a new value — the input is not mutated.
|
|
89
98
|
*/
|
|
90
|
-
export function sanitizeContent(content) {
|
|
99
|
+
export function sanitizeContent(content, options) {
|
|
91
100
|
if (typeof content === "string")
|
|
92
101
|
return content;
|
|
93
102
|
if (!Array.isArray(content))
|
|
@@ -95,6 +104,12 @@ export function sanitizeContent(content) {
|
|
|
95
104
|
let touched = false;
|
|
96
105
|
const out = [];
|
|
97
106
|
for (const block of content) {
|
|
107
|
+
const sensitiveReplacement = getSensitiveToolResultReplacement(block, options);
|
|
108
|
+
if (sensitiveReplacement !== undefined) {
|
|
109
|
+
out.push({ ...block, content: sensitiveReplacement });
|
|
110
|
+
touched = true;
|
|
111
|
+
continue;
|
|
112
|
+
}
|
|
98
113
|
if (isImageBlock(block)) {
|
|
99
114
|
out.push(sanitizeImageBlock(block));
|
|
100
115
|
touched = true;
|
|
@@ -114,11 +129,11 @@ export function sanitizeContent(content) {
|
|
|
114
129
|
* Returns the *same* array reference when no message held an image (fast
|
|
115
130
|
* path for the overwhelmingly common pure-text case).
|
|
116
131
|
*/
|
|
117
|
-
export function sanitizeMessages(messages) {
|
|
132
|
+
export function sanitizeMessages(messages, options) {
|
|
118
133
|
let touched = false;
|
|
119
134
|
const out = [];
|
|
120
135
|
for (const m of messages) {
|
|
121
|
-
const sanitized = sanitizeContent(m.content);
|
|
136
|
+
const sanitized = sanitizeContent(m.content, options);
|
|
122
137
|
if (sanitized !== m.content) {
|
|
123
138
|
touched = true;
|
|
124
139
|
out.push({ ...m, content: sanitized });
|
|
@@ -5,6 +5,9 @@ export interface UpdateCheck {
|
|
|
5
5
|
latestCommit?: string;
|
|
6
6
|
reason?: string;
|
|
7
7
|
}
|
|
8
|
+
export interface CheckPluginUpdateOptions {
|
|
9
|
+
allowUnsafeTransport?: boolean;
|
|
10
|
+
}
|
|
8
11
|
/**
|
|
9
12
|
* Check whether a remote (git-sourced) plugin has a newer commit upstream,
|
|
10
13
|
* WITHOUT cloning. Compares the recorded install commit (meta.commit) against
|
|
@@ -13,4 +16,4 @@ export interface UpdateCheck {
|
|
|
13
16
|
* an explanatory `reason` rather than throwing — the only hard error is an
|
|
14
17
|
* unknown plugin name.
|
|
15
18
|
*/
|
|
16
|
-
export declare function checkPluginUpdate(name: string): Promise<UpdateCheck>;
|
|
19
|
+
export declare function checkPluginUpdate(name: string, options?: CheckPluginUpdateOptions): Promise<UpdateCheck>;
|
|
@@ -11,12 +11,14 @@ import { CSMeta, PluginInstallError } from "./types.js";
|
|
|
11
11
|
* an explanatory `reason` rather than throwing — the only hard error is an
|
|
12
12
|
* unknown plugin name.
|
|
13
13
|
*/
|
|
14
|
-
export async function checkPluginUpdate(name) {
|
|
14
|
+
export async function checkPluginUpdate(name, options = {}) {
|
|
15
15
|
const metaPath = pluginMetaPath(name);
|
|
16
16
|
if (!existsSync(metaPath))
|
|
17
17
|
throw new PluginInstallError(`no plugin named '${name}'`);
|
|
18
18
|
const meta = CSMeta.parse(JSON.parse(readFileSync(metaPath, "utf-8")));
|
|
19
|
-
const parsed = parseSource(meta.source
|
|
19
|
+
const parsed = parseSource(meta.source, {
|
|
20
|
+
allowUnsafeTransport: options.allowUnsafeTransport === true,
|
|
21
|
+
});
|
|
20
22
|
if (parsed.kind !== "remote") {
|
|
21
23
|
return { name, updateAvailable: false, reason: "not a remote source" };
|
|
22
24
|
}
|
|
@@ -9,6 +9,7 @@ import { resolveCodexMcpServers } from "./codex/convertMcp.js";
|
|
|
9
9
|
import { copyCodexSkills } from "./codex/convertSkills.js";
|
|
10
10
|
import { copyCodexCommands } from "./codex/convertCommands.js";
|
|
11
11
|
import { appendInstallEntry, pluginInstallKey } from "../installedPlugins.js";
|
|
12
|
+
import { rewritePluginVars } from "../varRewrite.js";
|
|
12
13
|
/**
|
|
13
14
|
* Install a local plugin directory into ~/.code-shell/plugins/<name>/.
|
|
14
15
|
* Builds into a temp sibling dir, then renames into place — a conversion
|
|
@@ -63,6 +64,7 @@ export async function installPluginFromPath(sourceDir, name, installedAt) {
|
|
|
63
64
|
}
|
|
64
65
|
meta = { name, format: "codex", version: manifest.version, source: sourceDir, installedAt };
|
|
65
66
|
}
|
|
67
|
+
rewritePluginVars(tmpDir);
|
|
66
68
|
await writeFile(join(tmpDir, ".cs-meta.json"), JSON.stringify(meta, null, 2));
|
|
67
69
|
await rename(tmpDir, finalDir);
|
|
68
70
|
// Register so existing loaders (scanInstalledPlugins / loadPluginHooks)
|
|
@@ -5,6 +5,7 @@ import { gitClone, gitRevParseHead } from "../gitOps.js";
|
|
|
5
5
|
import { installPluginFromPath } from "./install.js";
|
|
6
6
|
import { pluginMetaPath } from "./paths.js";
|
|
7
7
|
import { PluginInstallError } from "./types.js";
|
|
8
|
+
import { resolveContainedPluginSubpath } from "./sourcePath.js";
|
|
8
9
|
/**
|
|
9
10
|
* Remote install orchestrator: a thin bridge over the existing pieces. Clone
|
|
10
11
|
* the git source to a private temp dir, hand the (sub)directory to the local
|
|
@@ -26,7 +27,14 @@ export async function installPluginFromSource(parsed, name, installedAt) {
|
|
|
26
27
|
if (!clone.ok) {
|
|
27
28
|
throw new PluginInstallError(`clone failed: ${clone.error}`);
|
|
28
29
|
}
|
|
29
|
-
const realSrc = parsed.subdir
|
|
30
|
+
const realSrc = parsed.subdir
|
|
31
|
+
? (() => {
|
|
32
|
+
const resolved = resolveContainedPluginSubpath(tmp, parsed.subdir, "subdir");
|
|
33
|
+
if (!resolved.ok)
|
|
34
|
+
throw new PluginInstallError(resolved.error);
|
|
35
|
+
return resolved.path;
|
|
36
|
+
})()
|
|
37
|
+
: tmp;
|
|
30
38
|
if (!existsSync(realSrc) || !statSync(realSrc).isDirectory()) {
|
|
31
39
|
throw new PluginInstallError(`subdir not found in repo: ${parsed.subdir}`);
|
|
32
40
|
}
|
|
@@ -17,4 +17,7 @@ export type ParsedSource = {
|
|
|
17
17
|
raw: string;
|
|
18
18
|
inferredName: string;
|
|
19
19
|
};
|
|
20
|
-
export
|
|
20
|
+
export interface ParseSourceOptions {
|
|
21
|
+
allowUnsafeTransport?: boolean;
|
|
22
|
+
}
|
|
23
|
+
export declare function parseSource(input: string, options?: ParseSourceOptions): ParsedSource;
|
|
@@ -1,16 +1,30 @@
|
|
|
1
1
|
import { resolve } from "node:path";
|
|
2
2
|
import { githubRepoToCloneUrl } from "../gitOps.js";
|
|
3
|
+
import { PluginInstallError } from "./types.js";
|
|
3
4
|
/** SSH shorthand `git@host:org/repo.git` — has a `:` after the `git@host` part. */
|
|
4
5
|
function isSshUrl(s) {
|
|
5
6
|
return /^[^/]+@[^/]+:/.test(s) && !s.includes("://");
|
|
6
7
|
}
|
|
7
8
|
function isRemote(s) {
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
9
|
+
const lower = s.toLowerCase();
|
|
10
|
+
return lower.startsWith("github:") || /^[a-z][a-z0-9+.-]*:\/\//i.test(s) || isSshUrl(s);
|
|
11
|
+
}
|
|
12
|
+
function unsafeTransport(input) {
|
|
13
|
+
const scheme = input.match(/^([a-z][a-z0-9+.-]*):\/\//i)?.[1]?.toLowerCase();
|
|
14
|
+
if (!scheme)
|
|
15
|
+
return null;
|
|
16
|
+
if (scheme === "https")
|
|
17
|
+
return null;
|
|
18
|
+
return `${scheme}://`;
|
|
19
|
+
}
|
|
20
|
+
function lowerUrlScheme(input) {
|
|
21
|
+
return input.replace(/^([a-z][a-z0-9+.-]*):/i, (scheme) => scheme.toLowerCase());
|
|
22
|
+
}
|
|
23
|
+
function hasGithubScheme(input) {
|
|
24
|
+
return input.slice(0, "github:".length).toLowerCase() === "github:";
|
|
25
|
+
}
|
|
26
|
+
function stripGithubScheme(input) {
|
|
27
|
+
return input.slice("github:".length);
|
|
14
28
|
}
|
|
15
29
|
/** Last path segment of a repo url/path, with a trailing `.git` stripped. */
|
|
16
30
|
function repoNameFromUrl(url) {
|
|
@@ -22,10 +36,14 @@ function repoNameFromUrl(url) {
|
|
|
22
36
|
function lastSegment(p) {
|
|
23
37
|
return p.split("/").filter(Boolean).pop() ?? p;
|
|
24
38
|
}
|
|
25
|
-
export function parseSource(input) {
|
|
39
|
+
export function parseSource(input, options = {}) {
|
|
26
40
|
if (!isRemote(input)) {
|
|
27
41
|
return { kind: "local", path: resolve(input) };
|
|
28
42
|
}
|
|
43
|
+
const unsafe = unsafeTransport(input);
|
|
44
|
+
if (unsafe && !options.allowUnsafeTransport) {
|
|
45
|
+
throw new PluginInstallError(`unsafe plugin source transport '${unsafe}' is disabled by default; use https://, github:, SSH, or pass allowUnsafeTransport explicitly`);
|
|
46
|
+
}
|
|
29
47
|
const raw = input;
|
|
30
48
|
// 1. Split off `#subdir` (last `#`).
|
|
31
49
|
let rest = input;
|
|
@@ -58,11 +76,11 @@ export function parseSource(input) {
|
|
|
58
76
|
}
|
|
59
77
|
// 3. Normalize url.
|
|
60
78
|
let url;
|
|
61
|
-
if (base
|
|
62
|
-
url = githubRepoToCloneUrl(base
|
|
79
|
+
if (hasGithubScheme(base)) {
|
|
80
|
+
url = githubRepoToCloneUrl(stripGithubScheme(base));
|
|
63
81
|
}
|
|
64
82
|
else {
|
|
65
|
-
url = base;
|
|
83
|
+
url = lowerUrlScheme(base);
|
|
66
84
|
}
|
|
67
85
|
const inferredName = subdir ? lastSegment(subdir) : repoNameFromUrl(url);
|
|
68
86
|
const result = { kind: "remote", url, raw, inferredName };
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export type ContainedPluginSubpathResult = {
|
|
2
|
+
ok: true;
|
|
3
|
+
path: string;
|
|
4
|
+
} | {
|
|
5
|
+
ok: false;
|
|
6
|
+
error: string;
|
|
7
|
+
};
|
|
8
|
+
export declare function validateRelativePluginSubpath(subpath: string, label: string): string | null;
|
|
9
|
+
export declare function resolveContainedPluginSubpath(root: string, subpath: string, label: string): ContainedPluginSubpathResult;
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { realpathSync } from "node:fs";
|
|
2
|
+
import { isAbsolute, resolve, sep } from "node:path";
|
|
3
|
+
function normPath(path) {
|
|
4
|
+
return process.platform === "win32" ? path.toLowerCase() : path;
|
|
5
|
+
}
|
|
6
|
+
function isContainedOrRoot(child, parent) {
|
|
7
|
+
const c = normPath(child);
|
|
8
|
+
const parentPath = normPath(parent);
|
|
9
|
+
const parentPrefix = normPath(parent.endsWith(sep) ? parent : parent + sep);
|
|
10
|
+
return c === parentPath || c.startsWith(parentPrefix);
|
|
11
|
+
}
|
|
12
|
+
export function validateRelativePluginSubpath(subpath, label) {
|
|
13
|
+
if (typeof subpath !== "string" || subpath.length === 0) {
|
|
14
|
+
return `${label} must be a non-empty relative path`;
|
|
15
|
+
}
|
|
16
|
+
if (subpath.includes("\0")) {
|
|
17
|
+
return `${label} must not contain NUL bytes: ${subpath}`;
|
|
18
|
+
}
|
|
19
|
+
if (isAbsolute(subpath)) {
|
|
20
|
+
return `${label} must be relative and inside the source tree: ${subpath}`;
|
|
21
|
+
}
|
|
22
|
+
if (subpath.split(/[\\/]+/).includes("..")) {
|
|
23
|
+
return `${label} must not contain parent-directory segments: ${subpath}`;
|
|
24
|
+
}
|
|
25
|
+
return null;
|
|
26
|
+
}
|
|
27
|
+
export function resolveContainedPluginSubpath(root, subpath, label) {
|
|
28
|
+
const invalid = validateRelativePluginSubpath(subpath, label);
|
|
29
|
+
if (invalid)
|
|
30
|
+
return { ok: false, error: invalid };
|
|
31
|
+
let realRoot;
|
|
32
|
+
try {
|
|
33
|
+
realRoot = realpathSync(root);
|
|
34
|
+
}
|
|
35
|
+
catch (err) {
|
|
36
|
+
return { ok: false, error: `${label} root could not be resolved: ${err.message}` };
|
|
37
|
+
}
|
|
38
|
+
const candidate = resolve(root, subpath);
|
|
39
|
+
let realCandidate;
|
|
40
|
+
try {
|
|
41
|
+
realCandidate = realpathSync(candidate);
|
|
42
|
+
}
|
|
43
|
+
catch {
|
|
44
|
+
return { ok: false, error: `${label} not found in source tree: ${subpath}` };
|
|
45
|
+
}
|
|
46
|
+
if (!isContainedOrRoot(realCandidate, realRoot)) {
|
|
47
|
+
return { ok: false, error: `${label} escapes the source tree: ${subpath}` };
|
|
48
|
+
}
|
|
49
|
+
return { ok: true, path: realCandidate };
|
|
50
|
+
}
|
|
@@ -2,6 +2,9 @@ export interface UpdateResult {
|
|
|
2
2
|
updated: boolean;
|
|
3
3
|
reason: string;
|
|
4
4
|
}
|
|
5
|
+
export interface UpdatePluginOptions {
|
|
6
|
+
allowUnsafeTransport?: boolean;
|
|
7
|
+
}
|
|
5
8
|
/**
|
|
6
9
|
* Reinstall a plugin atomically: a failed update leaves the OLD plugin intact.
|
|
7
10
|
*
|
|
@@ -25,4 +28,4 @@ export declare function reinstallAtomic(name: string, source: string, doInstall:
|
|
|
25
28
|
* no local version file to compare, so update is always a fresh pull
|
|
26
29
|
* (equivalent to `--force`; cheap and reliable). See spec §9.
|
|
27
30
|
*/
|
|
28
|
-
export declare function updatePluginByName(name: string, installedAt: string, force: boolean): Promise<UpdateResult>;
|
|
31
|
+
export declare function updatePluginByName(name: string, installedAt: string, force: boolean, options?: UpdatePluginOptions): Promise<UpdateResult>;
|
|
@@ -6,7 +6,7 @@ import { pluginInstallDir } from "./paths.js";
|
|
|
6
6
|
import { installPluginFromPath } from "./install.js";
|
|
7
7
|
import { installPluginFromSource } from "./installFromSource.js";
|
|
8
8
|
import { parseSource } from "./parseSource.js";
|
|
9
|
-
import { pluginInstallKey, readInstalledPlugins, removeInstallEntries, writeInstalledPlugins } from "../installedPlugins.js";
|
|
9
|
+
import { pluginInstallKey, readInstalledPlugins, removeInstallEntries, writeInstalledPlugins, } from "../installedPlugins.js";
|
|
10
10
|
import { CodexPluginManifest, CSMeta, PluginInstallError } from "./types.js";
|
|
11
11
|
/**
|
|
12
12
|
* Reinstall a plugin atomically: a failed update leaves the OLD plugin intact.
|
|
@@ -66,13 +66,15 @@ export async function reinstallAtomic(name, source, doInstall) {
|
|
|
66
66
|
* no local version file to compare, so update is always a fresh pull
|
|
67
67
|
* (equivalent to `--force`; cheap and reliable). See spec §9.
|
|
68
68
|
*/
|
|
69
|
-
export async function updatePluginByName(name, installedAt, force) {
|
|
69
|
+
export async function updatePluginByName(name, installedAt, force, options = {}) {
|
|
70
70
|
const dir = pluginInstallDir(name);
|
|
71
71
|
const metaPath = join(dir, ".cs-meta.json");
|
|
72
72
|
if (!existsSync(metaPath))
|
|
73
73
|
throw new PluginInstallError(`no plugin named '${name}'`);
|
|
74
74
|
const meta = CSMeta.parse(JSON.parse(readFileSync(metaPath, "utf-8")));
|
|
75
|
-
const parsed = parseSource(meta.source
|
|
75
|
+
const parsed = parseSource(meta.source, {
|
|
76
|
+
allowUnsafeTransport: options.allowUnsafeTransport === true,
|
|
77
|
+
});
|
|
76
78
|
if (parsed.kind === "remote") {
|
|
77
79
|
// No local version to diff against — always re-clone and reinstall.
|
|
78
80
|
await reinstallAtomic(name, meta.source, () => installPluginFromSource(parsed, name, installedAt));
|
|
@@ -4,11 +4,14 @@
|
|
|
4
4
|
* local absolute paths, github shorthand, https git URLs, and ssh git URLs.
|
|
5
5
|
*/
|
|
6
6
|
import type { MarketplaceSource } from "./types.js";
|
|
7
|
+
export interface ParseMarketplaceInputOptions {
|
|
8
|
+
allowUnsafeTransport?: boolean;
|
|
9
|
+
}
|
|
7
10
|
/**
|
|
8
11
|
* Returns the parsed source, or null when the input does not match any
|
|
9
12
|
* supported pattern. Callers should show a usage hint on null.
|
|
10
13
|
*/
|
|
11
|
-
export declare function parseMarketplaceInput(input: string): MarketplaceSource | null;
|
|
14
|
+
export declare function parseMarketplaceInput(input: string, options?: ParseMarketplaceInputOptions): MarketplaceSource | null;
|
|
12
15
|
/**
|
|
13
16
|
* Derive a stable marketplace name from a source. Used as the filesystem
|
|
14
17
|
* directory and the key in known_marketplaces.json.
|
|
@@ -7,15 +7,14 @@
|
|
|
7
7
|
* Returns the parsed source, or null when the input does not match any
|
|
8
8
|
* supported pattern. Callers should show a usage hint on null.
|
|
9
9
|
*/
|
|
10
|
-
export function parseMarketplaceInput(input) {
|
|
10
|
+
export function parseMarketplaceInput(input, options = {}) {
|
|
11
11
|
const trimmed = input.trim();
|
|
12
12
|
if (trimmed === "")
|
|
13
13
|
return null;
|
|
14
14
|
// Absolute local path to a git repository (bare or with .git suffix).
|
|
15
15
|
// Useful for dev workflows where the marketplace lives on disk rather
|
|
16
16
|
// than at a remote URL. git clone itself accepts the same form.
|
|
17
|
-
if ((trimmed.startsWith("/") || /^[a-zA-Z]:[\\/]/.test(trimmed)) &&
|
|
18
|
-
trimmed.endsWith(".git")) {
|
|
17
|
+
if ((trimmed.startsWith("/") || /^[a-zA-Z]:[\\/]/.test(trimmed)) && trimmed.endsWith(".git")) {
|
|
19
18
|
return { source: "git", url: trimmed };
|
|
20
19
|
}
|
|
21
20
|
// SSH: user@host:path[.git]
|
|
@@ -26,6 +25,8 @@ export function parseMarketplaceInput(input) {
|
|
|
26
25
|
}
|
|
27
26
|
// HTTPS
|
|
28
27
|
if (trimmed.startsWith("https://") || trimmed.startsWith("http://")) {
|
|
28
|
+
if (trimmed.startsWith("http://") && !options.allowUnsafeTransport)
|
|
29
|
+
return null;
|
|
29
30
|
let parsed;
|
|
30
31
|
try {
|
|
31
32
|
parsed = new URL(trimmed);
|