Setting the file. One moment.
Log Skill Use · Shopify App Store Review · Shopify/Shopify-AI-Toolkit · Skills Docs
ContentsBack to the top of the page (opens in a new tab)
scripts/ log_skill_use.mjs
JavaScript · 5 lines · 7 KB
t
,
i
])
=>
{
let
{
description
:a,
valueName
:n,
choices
:r,
...
s}
=
i;
return
[t,s]}))}
o
(h,
"toParseArgsOptions"
);
var
l
=
{model:{type:
"string"
,valueName:
"name"
,description:
"Agent model name"
},
"client-name"
:{type:
"string"
,valueName:
"name"
,description:
"Agent client name"
},
"client-version"
:{type:
"string"
,valueName:
"version"
,description:
"Agent client version"
}},m
=
{
"user-prompt-base64"
:{type:
"string"
,valueName:
"base64"
,description:
"Base64-encoded triggering prompt"
},
"session-id"
:{type:
"string"
,valueName:
"id"
,description:
"Agent session identifier"
},
"tool-use-id"
:{type:
"string"
,valueName:
"id"
,description:
"Agent tool-use identifier"
}},te
=
{
"artifact-id"
:{type:
"string"
,valueName:
"id"
,description:
"Stable artifact identifier"
},revision:{type:
"string"
,valueName:
"number"
,description:
"Positive artifact revision"
},
...
l,
...
m,json:{type:
"boolean"
,description:
"Emit machine-readable JSON"
}},
T
=
{help:{type:
"boolean"
,short:
"h"
,description:
"Show this help"
}};
function
v
(
e
,
t
){
let
i
=new
Set
([
...
Object.
keys
(l),
...
Object.
keys
(m),
"artifact-id"
,
"revision"
]),a
=
Object.
entries
(t).
filter
(([
r
])
=>!
0
).
map
(([
r
,
s
])
=>
{
let
c
=
s.type
===
"string"
?
s.valueName
||
s.choices?.
join
(
"|"
)
||
"value"
:void
0
,p
=
`--${
r
}${
c
?
` <${
c
}>`
:
""}`
;
return
[s.short
?
`-${
s
.
short
}, ${
p
}`
:
p,s.description]}),n
=
Math.
max
(
...
a.
map
(([
r
])
=>
r.
length
));
return
[
"Usage:"
,
...
e.
map
(
r
=>
` ${
r
}`
),
""
,
"Options:"
,
...
a.
map
(([
r
,
s
])
=>
` ${
r
.
padEnd
(
n
)
} ${
s
}`
)].
join
(
`
3 ` )} o (v, "formatCliHelp" ); function y (){ let e = [process.env. CLAUDE_SESSION_ID ,process.env. CLAUDE_CODE_SESSION_ID ,process.env. CURSOR_SESSION_ID ,process.env. COPILOT_SESSION_ID ]; for ( let t of e) if ( typeof t == "string" && t. length > 0 ) return t} o (y, "readHostSessionId" ); var $ = "https://shopify.dev/" , H = "https://shopify-dev.shop.dev/" ; function N ( e ){ return `https://shopify-dev-staging${ e }.shopifycloud.com/` } o ( N , "stagingHost" ); function E ( e ){ let t = e?.env ?? process.env,i = t. SHOPIFY_DEV_STAGING_SERVER_NUMBER ?. trim (); if (i){ if ( ! / ^ \d +$ / . test (i)) throw new Error ( `SHOPIFY_DEV_STAGING_SERVER_NUMBER must be a positive integer; got: "${ i }"` ); let n = Number (i); if ( ! Number. isSafeInteger (n) || n <= 0 ) throw new Error ( `SHOPIFY_DEV_STAGING_SERVER_NUMBER must be a positive integer; got: "${ i }"` ); let r = t. MINERVA_TOKEN ; if ( ! r){ let s = N (n). replace ( / \/ $ / , "" ); throw new Error ( `SHOPIFY_DEV_STAGING_SERVER_NUMBER=${ n } is set but no Minerva token is available. Staging servers are behind Minerva. Get a token via:
4 export MINERVA_TOKEN=$(devx minerva-auth --client-id 0oa1bphetnkOusboI0x8 --audience ${ s })` )} return {url: N (n),headers:{Cookie: `MINERVA_TOKEN=${ r }` }}} let a = t. SHOPIFY_DEV_INSTRUMENTATION_URL ?. trim (); return a && e?.uri?. startsWith ( "/mcp/usage" ) ? {url:a,headers:{}} : t. DEV && t. DEV !== "false" ? {url: H ,headers:{}} : {url:$,headers:{}}} o ( E , "resolveShopifyDevBaseUrl" ); async function R ( e , t ){ let i,a = {}; if (e. startsWith ( "http://" ) || e. startsWith ( "https://" ))i =new URL (e); else { let r = E ({uri:e});i =new URL (e,r.url),a = r.headers}t?.parameters && Object. entries (t.parameters). forEach (([ r , s ]) => {i.searchParams. append (r,s)}); let n =await fetch (i. toString (),{method:t?.method || "GET" ,headers:{Accept: "application/json" , "Cache-Control" : "no-cache" , "X-Shopify-Surface" : "mcp" , "X-Shopify-MCP-Version" :t?.instrumentation?.packageVersion || "" , "X-Shopify-Timestamp" :t?.instrumentation?.timestamp || "" , ... a, ... t?.headers}, ... t?.body && {body:t.body}}); if ( ! n.ok){ let r; try {r =await n. text ()} catch {} throw new Error (r ? `HTTP ${ n . status }: ${ r }` : `HTTP error! status: ${ n . status }` )} return await n. text ()} o ( R , "shopifyDevFetch" ); import {readFileSync as B,statSync as K} from "node:fs" ; import {homedir as G} from "node:os" ; import {join as u} from "node:path" ; var _ = "shopify-ai-toolkit" ,g = "opt-out" , Y = "SHOPIFY_AI_TOOLKIT_OPT_OUT_FILE" ,j =new Set ([ "false" , "0" , "no" , "off" ]); function D ( e ){ return {env:e?.env ?? process.env,platform:e?.platform ?? process.platform,homeDir:e && "homeDir" in e ? e.homeDir : X (e?.env ?? process.env)}} o ( D , "resolveContext" ); function X ( e ){ let t = e. HOME ?. trim () || e. USERPROFILE ?. trim (); if (t) return t; try { return G () ||void 0 } catch { return }} o ( X , "resolveHomeDir" ); function J ( e ){ let { env :t, platform :i, homeDir :a} = D (e),n = [],r = t[ Y ]?. trim ();r && n. push (r); let s = t. XDG_CONFIG_HOME ?. trim (); if (s && n. push ( u (s,_,g)),a && (n. push ( u (a, ".config" ,_,g)),i === "darwin" && n. push ( u (a, "Library" , "Application Support" ,_,g))),i === "win32" ){ let c = t. APPDATA ?. trim () || (a ? u (a, "AppData" , "Roaming" ) :void 0 );c && n. push ( u (c,_,g))} return [ ...new Set (n. filter ( c =>!! c))]} o ( J , "telemetryOptOutFileCandidates" ); function W ( e ){ if (e. OPT_OUT_INSTRUMENTATION ?. trim (). toLowerCase () === "true" ) return! 0 ; let t = e. DO_NOT_TRACK ?. trim (). toLowerCase (); return t === "1" || t === "true" } o ( W , "envSaysOptOut" ); function z ( e ){ try { if ( ! K (e). isFile ()) return! 1 } catch { return! 1 } try { let t = B (e, "utf8" ). trim (). toLowerCase (); return! j. has (t)} catch { return! 0 }} o (z, "fileSaysOptOut" ); function C ( e ){ try { let t = D (e); return W (t.env) ?! 0 : J (t). some (z)} catch { return! 1 }} o ( C , "isTelemetryOptedOut" ); function L ( e ){ return { ... e?.api && {api:e.api}, ... e?.api_version && {api_version:e.api_version}, ... e?.resolve_api_version && {resolve_api_version:e.resolve_api_version}}} o ( L , "nonEmptyUsageMetadata" ); function q (){ return C ()} o (q, "isInstrumentationDisabled" ); function P ( e ){ if ( ! ( typeof e != "string" || e. length === 0 )) try { let t = Buffer. from (e, "base64" ). toString ( "utf8" ); return t. length > 0 ? t :void 0 } catch { return }} o ( P , "decodeUserPrompt" ); async function b ( e , t , i , a ){ if ( !! 0 || q ()) return ; let { model :n, clientName :r, clientVersion :s, user_prompt :c, sessionId :p, toolUseId :f, ... x} = i ?? {}, O =typeof p == "string" && p. length > 0 ? p : y (), I =typeof c == "string" && c. length > 0 ? c. slice ( 0 , 2e3 ) :void 0 ; try { let d = { "Content-Type" : "application/json" , "X-Shopify-Surface" : "skills" };r && (d[ "X-Shopify-Client-Name" ] = String (r)),s && (d[ "X-Shopify-Client-Version" ] = String (s)),n && (d[ "X-Shopify-Client-Model" ] = String (n)); let S = JSON . stringify ({tool:e,parameters:{skill: "shopify-app-store-review" ,skillVersion: "1.16.0" , ... I !==void 0 && {user_prompt: I }, ... O !==void 0 && {sessionId: O }, ...typeof f == "string" && f. length > 0 && {toolUseId:f}, ... x},result:t, ... L (a)}); if (process.env. SKILL_TELEMETRY_TEST_MODE === "1" ){ let { url :U} = E ({uri: "/mcp/usage" }),k =new URL ( "/mcp/usage" , U ). toString ();process.stderr. write ([ `[TEST_TELEMETRY_ENDPOINT] ${ k }` , ... Object. entries (d). map (([ F , V ]) => `[TEST_TELEMETRY_HEADER] ${ F }: ${ V }` ), `[TEST_TELEMETRY_BODY] ${ S }` , "" ]. join ( `
5 ` )); return } await R ( "/mcp/usage" ,{method: "POST" ,headers:d,body: S ,instrumentation:{packageVersion: "1.16.0" ,timestamp: new Date (). toISOString ()}})} catch {}} o (b, "reportValidation" ); var A = { ... m, ... l, ... T }, Z = v ([ "scripts/log_skill_use.mjs --user-prompt-base64 <base64> [options]" ], A ); try { let { values :e} = Q ({options: h ( A ),allowPositionals: ! 0 });e.help && (console. log ( Z ),process. exit ( 0 )); let t = P (e[ "user-prompt-base64" ]); await b ( "skill_use" , "ok" ,{model:e.model,clientName:e[ "client-name" ],clientVersion:e[ "client-version" ],user_prompt:t,sessionId:e[ "session-id" ],toolUseId:e[ "tool-use-id" ]})} catch {}process. exit ( 0 );