teamcopilot 0.4.6 → 0.4.9
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/frontend/assets/{cssMode-BvYN4KKH.js → cssMode-CE53d2hg.js} +1 -1
- package/dist/frontend/assets/{freemarker2-B6ckzfiM.js → freemarker2-CJGHZPtj.js} +1 -1
- package/dist/frontend/assets/{handlebars-B8tVPXO5.js → handlebars-BzFXNnGb.js} +1 -1
- package/dist/frontend/assets/{html-DofiBST0.js → html-C3n9IIyU.js} +1 -1
- package/dist/frontend/assets/{htmlMode-CFHyNphc.js → htmlMode-D79IcQEi.js} +1 -1
- package/dist/frontend/assets/{index-RBzaHHSW.js → index-D78DyWXF.js} +3 -3
- package/dist/frontend/assets/{javascript-CV8e_whj.js → javascript-9bUNZ5lp.js} +1 -1
- package/dist/frontend/assets/{jsonMode-Bma8akFX.js → jsonMode-C2zi_Uik.js} +1 -1
- package/dist/frontend/assets/{liquid-reuNir37.js → liquid-4OpD43sJ.js} +1 -1
- package/dist/frontend/assets/{mdx-C064_z03.js → mdx-2Qz4Lvmc.js} +1 -1
- package/dist/frontend/assets/{python-BCTgwwjV.js → python-C_qSupC6.js} +1 -1
- package/dist/frontend/assets/{razor-DYdNy62q.js → razor-BP5l-iMJ.js} +1 -1
- package/dist/frontend/assets/{tsMode-NncZSZJ8.js → tsMode-DY4gCiV5.js} +1 -1
- package/dist/frontend/assets/{typescript-B9SNcInK.js → typescript-BAuc_RF9.js} +1 -1
- package/dist/frontend/assets/{xml-CB7h2Jhc.js → xml-BkgYKYnI.js} +1 -1
- package/dist/frontend/assets/{yaml-CkKQHzph.js → yaml-BJ7Mbgq8.js} +1 -1
- package/dist/frontend/index.html +1 -1
- package/dist/workspace_files/.opencode/plugins/runWorkflow.ts +39 -6
- package/dist/workspace_files/.opencode/plugins/secret-proxy.ts +97 -34
- package/package.json +1 -1
|
@@ -24,7 +24,9 @@ const SECRET_PLACEHOLDER_PATTERN = /\{\{SECRET:([A-Za-z_][A-Za-z0-9_]*)\}\}/g
|
|
|
24
24
|
const SECRET_ENV_REFERENCE_PATTERN = /\$\{__TEAMCOPILOT_RUNTIME_SECRET_([A-Z][A-Z0-9_]*)\}/g
|
|
25
25
|
const AGENT_VISIBLE_SECRET_ENV_REFERENCE_PATTERN = /__TEAMCOPILOT_RUNTIME_SECRET_[A-Z][A-Z0-9_]*/
|
|
26
26
|
const SECRET_ENV_PREFIX = "__TEAMCOPILOT_RUNTIME_SECRET_"
|
|
27
|
-
const SHELL_CONTROL_TOKENS = new Set(["&&", "||", ";", "|"])
|
|
27
|
+
const SHELL_CONTROL_TOKENS = new Set(["&&", "||", ";", "|", "\n"])
|
|
28
|
+
const SHELL_REDIRECTION_PATTERN = /^(\d+)?(?:>>?|<<?|<<<)$/
|
|
29
|
+
const SHELL_REDIRECTION_DUPLICATION_PATTERN = /^(\d+)?[<>]&\d+$/
|
|
28
30
|
const CURL_SAFE_VALUE_OPTIONS = new Set([
|
|
29
31
|
"-H",
|
|
30
32
|
"--header",
|
|
@@ -160,6 +162,45 @@ type CommandToken = {
|
|
|
160
162
|
end: number
|
|
161
163
|
}
|
|
162
164
|
|
|
165
|
+
function readShellRedirectionToken(command: string, start: number): string | null {
|
|
166
|
+
let index = start
|
|
167
|
+
while (/\d/.test(command[index] ?? "")) {
|
|
168
|
+
index += 1
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
if (command[index] !== ">" && command[index] !== "<") {
|
|
172
|
+
if (command[start] !== "&" || command[start + 1] !== ">") {
|
|
173
|
+
return null
|
|
174
|
+
}
|
|
175
|
+
index = start + 2
|
|
176
|
+
} else {
|
|
177
|
+
const operator = command[index]
|
|
178
|
+
index += 1
|
|
179
|
+
while (command[index] === operator && index - start < 4) {
|
|
180
|
+
index += 1
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
if (command[index] === "&") {
|
|
185
|
+
index += 1
|
|
186
|
+
while (/\d/.test(command[index] ?? "")) {
|
|
187
|
+
index += 1
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
return command.slice(start, index)
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
function isEscapedLineContinuation(command: string, newlineIndex: number): boolean {
|
|
195
|
+
let backslashCount = 0
|
|
196
|
+
let index = newlineIndex - 1
|
|
197
|
+
while (index >= 0 && command[index] === "\\") {
|
|
198
|
+
backslashCount += 1
|
|
199
|
+
index -= 1
|
|
200
|
+
}
|
|
201
|
+
return backslashCount % 2 === 1
|
|
202
|
+
}
|
|
203
|
+
|
|
163
204
|
function tokenizeCommand(command: string): CommandToken[] {
|
|
164
205
|
const tokens: CommandToken[] = []
|
|
165
206
|
const length = command.length
|
|
@@ -172,6 +213,9 @@ function tokenizeCommand(command: string): CommandToken[] {
|
|
|
172
213
|
}
|
|
173
214
|
|
|
174
215
|
if (/\s/.test(char)) {
|
|
216
|
+
if (char === "\n" && !isEscapedLineContinuation(command, index)) {
|
|
217
|
+
tokens.push({ raw: "\n", start: index, end: index + 1 })
|
|
218
|
+
}
|
|
175
219
|
index += 1
|
|
176
220
|
continue
|
|
177
221
|
}
|
|
@@ -195,6 +239,13 @@ function tokenizeCommand(command: string): CommandToken[] {
|
|
|
195
239
|
continue
|
|
196
240
|
}
|
|
197
241
|
|
|
242
|
+
const redirectionToken = readShellRedirectionToken(command, start)
|
|
243
|
+
if (redirectionToken !== null) {
|
|
244
|
+
index += redirectionToken.length
|
|
245
|
+
tokens.push({ raw: redirectionToken, start, end: index })
|
|
246
|
+
continue
|
|
247
|
+
}
|
|
248
|
+
|
|
198
249
|
while (index < length) {
|
|
199
250
|
const current = command[index]
|
|
200
251
|
if (current === undefined) {
|
|
@@ -243,6 +294,10 @@ function tokenizeCommand(command: string): CommandToken[] {
|
|
|
243
294
|
break
|
|
244
295
|
}
|
|
245
296
|
|
|
297
|
+
if (current === ">" || current === "<") {
|
|
298
|
+
break
|
|
299
|
+
}
|
|
300
|
+
|
|
246
301
|
index += 1
|
|
247
302
|
}
|
|
248
303
|
|
|
@@ -330,6 +385,16 @@ function isGitExecutableToken(rawToken: string): boolean {
|
|
|
330
385
|
return base === "git"
|
|
331
386
|
}
|
|
332
387
|
|
|
388
|
+
function isShellRedirectionToken(rawToken: string): boolean {
|
|
389
|
+
const { inner } = unwrapToken(rawToken)
|
|
390
|
+
return SHELL_REDIRECTION_PATTERN.test(inner) || SHELL_REDIRECTION_DUPLICATION_PATTERN.test(inner) || inner === "&>"
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
function redirectionConsumesNextToken(rawToken: string): boolean {
|
|
394
|
+
const { inner } = unwrapToken(rawToken)
|
|
395
|
+
return !SHELL_REDIRECTION_DUPLICATION_PATTERN.test(inner)
|
|
396
|
+
}
|
|
397
|
+
|
|
333
398
|
function getLongOptionName(inner: string): string | null {
|
|
334
399
|
const eqIndex = inner.indexOf("=")
|
|
335
400
|
const optionName = eqIndex === -1 ? inner : inner.slice(0, eqIndex)
|
|
@@ -701,6 +766,13 @@ export const SecretProxyPlugin: Plugin = async ({ client }) => {
|
|
|
701
766
|
break
|
|
702
767
|
}
|
|
703
768
|
|
|
769
|
+
if (isShellRedirectionToken(segmentToken.raw)) {
|
|
770
|
+
if (redirectionConsumesNextToken(segmentToken.raw)) {
|
|
771
|
+
j += 1
|
|
772
|
+
}
|
|
773
|
+
continue
|
|
774
|
+
}
|
|
775
|
+
|
|
704
776
|
const { inner } = unwrapToken(segmentToken.raw)
|
|
705
777
|
|
|
706
778
|
if (expectedValueKind !== null) {
|
|
@@ -834,6 +906,13 @@ export const SecretProxyPlugin: Plugin = async ({ client }) => {
|
|
|
834
906
|
break
|
|
835
907
|
}
|
|
836
908
|
|
|
909
|
+
if (isShellRedirectionToken(segmentToken.raw)) {
|
|
910
|
+
if (redirectionConsumesNextToken(segmentToken.raw)) {
|
|
911
|
+
j += 1
|
|
912
|
+
}
|
|
913
|
+
continue
|
|
914
|
+
}
|
|
915
|
+
|
|
837
916
|
const rewritten = rewriteGitRawToken(segmentToken.raw)
|
|
838
917
|
if (rewritten.rewritten !== segmentToken.raw) {
|
|
839
918
|
replacements.push({
|
|
@@ -879,41 +958,25 @@ export const SecretProxyPlugin: Plugin = async ({ client }) => {
|
|
|
879
958
|
assertNoAgentAuthoredSecretEnvReference(input.arguments)
|
|
880
959
|
|
|
881
960
|
const commandCache = new Map<string, { rewritten: string; referencedKeys: string[] }>()
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
961
|
+
const commandHasPlaceholder = typeof input.command === "string" && input.command.includes("{{SECRET:")
|
|
962
|
+
const argumentsHasPlaceholder = typeof input.arguments === "string" && input.arguments.includes("{{SECRET:")
|
|
963
|
+
if (commandHasPlaceholder || argumentsHasPlaceholder) {
|
|
964
|
+
const originalCommand = typeof input.command === "string" ? input.command : ""
|
|
965
|
+
const originalArguments = typeof input.arguments === "string" ? input.arguments : ""
|
|
966
|
+
const fullCommand = originalArguments.trim().length > 0
|
|
967
|
+
? `${originalCommand} ${originalArguments}`
|
|
968
|
+
: originalCommand
|
|
969
|
+
const rewritten = await maybeRewriteSupportedString(fullCommand, commandCache)
|
|
970
|
+
const prefix = `${originalCommand} `
|
|
971
|
+
|
|
972
|
+
if (rewritten.rewritten === fullCommand) {
|
|
973
|
+
input.command = originalCommand
|
|
974
|
+
input.arguments = originalArguments
|
|
975
|
+
} else if ((isCurlExecutableToken(originalCommand) || isGitExecutableToken(originalCommand)) && rewritten.rewritten.startsWith(prefix)) {
|
|
976
|
+
input.arguments = rewritten.rewritten.slice(prefix.length)
|
|
897
977
|
} else {
|
|
898
|
-
const rewritten = await maybeRewriteSupportedString(input.command, commandCache)
|
|
899
978
|
input.command = rewritten.rewritten
|
|
900
|
-
|
|
901
|
-
}
|
|
902
|
-
if (typeof input.arguments === "string" && input.arguments.includes("{{SECRET:")) {
|
|
903
|
-
if (isCurlExecutableToken(input.command) || isGitExecutableToken(input.command)) {
|
|
904
|
-
const fullCommand = input.arguments.trim().length > 0
|
|
905
|
-
? `${input.command} ${input.arguments}`
|
|
906
|
-
: input.command
|
|
907
|
-
const rewritten = isCurlExecutableToken(input.command)
|
|
908
|
-
? substitutePlaceholdersInCurlShellString(fullCommand)
|
|
909
|
-
: substitutePlaceholdersInGitShellString(fullCommand)
|
|
910
|
-
const prefix = `${input.command} `
|
|
911
|
-
if (rewritten.rewritten.startsWith(prefix)) {
|
|
912
|
-
input.arguments = rewritten.rewritten.slice(prefix.length)
|
|
913
|
-
}
|
|
914
|
-
} else {
|
|
915
|
-
const rewritten = await maybeRewriteSupportedString(input.arguments, commandCache)
|
|
916
|
-
input.arguments = rewritten.rewritten
|
|
979
|
+
input.arguments = ""
|
|
917
980
|
}
|
|
918
981
|
}
|
|
919
982
|
|